diff --git a/schemas/v1.1-dev/schema.yaml b/schemas/v1.1-dev/schema.yaml index 459cbef..9e78075 100644 --- a/schemas/v1.1-dev/schema.yaml +++ b/schemas/v1.1-dev/schema.yaml @@ -51,6 +51,8 @@ $defs: - array - number - "null" + copy: + type: string remove: type: boolean default: false diff --git a/tests/v1.1-dev/pass/copy-path-item-example.yaml b/tests/v1.1-dev/pass/copy-path-item-example.yaml new file mode 100644 index 0000000..529e486 --- /dev/null +++ b/tests/v1.1-dev/pass/copy-path-item-example.yaml @@ -0,0 +1,7 @@ +overlay: 1.1.0 +info: + title: Merge an existing path item with another one + version: 1.0.0 +actions: + - target: '$.paths["/bar"]' + copy: '$.paths["/foo"]' \ No newline at end of file diff --git a/versions/1.1.0-dev.md b/versions/1.1.0-dev.md index 8d74cc6..01b5f36 100644 --- a/versions/1.1.0-dev.md +++ b/versions/1.1.0-dev.md @@ -21,7 +21,7 @@ The main purpose of the Overlay Specification is to provide a way to repeatably ### Overlay -An Overlay is a JSON or YAML structure containing an ordered list of [Action Objects](#overlay-actions) that are to be applied to the target document. Each [Action Object](#action-object) has a `target` property and a modifier type (`update` or `remove`). The `target` property is a [[RFC9535|RFC9535 JSONPath]] query expression that identifies the elements of the target document to be updated and the modifier determines the change. +An Overlay is a JSON or YAML structure containing an ordered list of [Action Objects](#overlay-actions) that are to be applied to the target document. Each [Action Object](#action-object) has a `target` property and a modifier type (`update`, `remove`, or `copy`). The `target` property is a [[RFC9535|RFC9535 JSONPath]] query expression that identifies the elements of the target document to be updated and the modifier determines the change. ## Specification @@ -115,7 +115,8 @@ This object represents one or more changes to be applied to the target document | ---- | :----: | ---- | | target | `string` | **REQUIRED** A RFC9535 JSONPath query expression selecting nodes in the target document. | | description | `string` | A description of the action. [[CommonMark]] syntax MAY be used for rich text representation. | -| update | Any | If the `target` selects an object node, the value of this field MUST be an object with the properties and values to merge with the selected node. If the `target` selects an array, the value of this field MUST be an entry to append to the array. This field has no impact if the `remove` field of this action object is `true`. | +| update | Any | If the `target` selects an object node, the value of this field MUST be an object with the properties and values to merge with the selected node. If the `target` selects an array, the value of this field MUST be an entry to append to the array. This field has no impact if the `remove` field of this action object is `true` or if the `copy` field contains a value. | +| copy | `string` | A JSONPath expression selecting a single node to copy into the `target` nodes. If the `target` selects an object node, the value of this field MUST be an object with the properties and values to merge with the selected node. If the `target` selects an array, the value of this field MUST be an entry to append to the array. This field has no impact if the `remove` field of this action object is `true` or if the `update` field contains a value. | | remove | `boolean` | A boolean value that indicates that the target object or array MUST be removed from the the map or array it is contained in. The default value is `false`. | The result of the `target` JSONPath expression MUST be zero or more objects or arrays (not primitive types or `null` values). Should the `target` JSONPath result in selecting two or more nodes, they MUST be either all objects or all arrays. @@ -126,6 +127,8 @@ Primitive-valued items of an array cannot be replaced or removed individually, o The properties of the `update` object MUST be compatible with the target object referenced by the JSONPath key. When the Overlay document is applied, the properties in the `update` object are recursively merged with the properties in the target object with the same names; new properties are added to the target object. +The properties of the resolved `copy` object MUST be compatible with the target object referenced by the JSONPath key. When the Overlay document is applied, the properties in the resolved `copy` object are recursively merged with the properties in the target object with the same names; new properties are added to the target object. + This object MAY be extended with [Specification Extensions](#specification-extensions). ### Examples @@ -267,6 +270,200 @@ actions: This approach allows inversion of control as to where the Overlay updates apply to the target document itself. +#### Copy example + +Copy actions behave similarly to `update` actions but source the node to from the document being transformed. Copy `actions` MAY be used in sequence with `update` or `remove` actions to perform more advanced transformations like moving or renaming nodes. + +##### Simple copy + +This example shows how to copy all operations from the `items` path item to the `some-items` path item. + +###### Source description + +```yaml +openapi: 3.1.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + /some-items: + delete: + responses: + 200: + description: OK +``` + +###### Overlay + +```yaml +overlay: 1.1.0 +info: + title: Copy contents of an existing path to a new location + version: 1.0.0 +actions: + - target: '$.paths["/some-items"]' + copy: '$.paths["/items"]' + description: 'copies recursively all elements from the "items" path item to the new "some-items" path item without ensuring the node exists before the copy' +``` + +###### Result description + +```yaml +openapi: 3.1.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + /some-items: + get: + responses: + 200: + description: OK + delete: + responses: + 200: + description: OK +``` + +##### Ensure the target exists and copy + +This example shows how to copy all operations from the `items` path item to the `other-items` path item after first ensuring the target exists with an update action. + +###### Source description + +```yaml +openapi: 3.1.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + /some-items: + delete: + responses: + 200: + description: OK +``` + +###### Overlay + +```yaml +overlay: 1.1.0 +info: + title: Create a path and copy the contents of an existing path to the new path + version: 1.0.0 +actions: + - target: '$.paths' + update: { "/other-items": {} } + - target: '$.paths["/other-items"]' + copy: '$.paths["/items"]' + description: 'copies recursively all elements from the "items" path item to the new "other-items" path item while ensuring the node exists before the copy' +``` + +###### Result description + +```yaml +openapi: 3.1.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + /other-items: + get: + responses: + 200: + description: OK + /some-items: + delete: + responses: + 200: + description: OK +``` + +##### Move example + +This example shows how to rename the `items` path item to `new-items` using a sequence of overlay actions: + +1. Use an `update` action to ensure the target path item exists. +2. Use a `copy` action to copy the source path item to the target. +3. Use a `remove` action to delete the original source path item. + +###### Source description + +```yaml +openapi: 3.1.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + /some-items: + delete: + responses: + 200: + description: OK +``` + +###### Overlay + +```yaml +overlay: 1.1.0 +info: + title: Update the path for an API endpoint + version: 1.0.0 +actions: + - target: '$.paths' + update: { "/new-items": {} } + - target: '$.paths["/new-items"]' + copy: '$.paths["/items"]' + - target: '$.paths["/items"]' + remove: true + description: 'moves (renames) the "items" path item to "new-items"' +``` + +###### Result description + +```yaml +openapi: 3.1.0 +info: + title: Example API + version: 1.0.0 +paths: + /new-items: + get: + responses: + 200: + description: OK + /some-items: + delete: + responses: + 200: + description: OK +``` + ### Specification Extensions While the Overlay Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.