diff --git a/schemas/v1.2-dev/schema.yaml b/schemas/v1.2-dev/schema.yaml index 4891415..a4b6c3b 100644 --- a/schemas/v1.2-dev/schema.yaml +++ b/schemas/v1.2-dev/schema.yaml @@ -16,7 +16,11 @@ properties: minItems: 1 uniqueItems: true items: - $ref: "#/$defs/action-object" + oneOf: + - $ref: "#/$defs/reusable-action-reference-object" + - $ref: "#/$defs/action-object" + components: + $ref: "#/$defs/components-object" required: - overlay - info @@ -24,6 +28,60 @@ required: $ref: "#/$defs/specification-extensions" unevaluatedProperties: false $defs: + reusable-action-reference-object: + type: object + allOf: + - $ref: "#/$defs/specification-extensions" + - $ref: "#/$defs/action-object-base" + properties: + $ref: + type: string + pattern: ^#\/components\/actions\/(?:[^~/]|~0|~1)+$ + parameterValues: + type: object + additionalProperties: + type: string + required: + - $ref + $ref: "#/$defs/specification-extensions" + unevaluatedProperties: false + reusable-action-object-parameter: + type: object + properties: + name: + type: string + pattern: ^[A-Za-z_][A-Za-z_0-9]*$ + default: + type: string + required: + - name + description: A parameter to be used in a reusable action object + $ref: "#/$defs/specification-extensions" + unevaluatedProperties: false + reusable-action-object: + type: object + allOf: + - $ref: "#/$defs/specification-extensions" + - $ref: "#/$defs/action-object-base" + properties: + parameters: + type: array + items: + $ref: "#/$defs/reusable-action-object-parameter" + environmentVariables: + type: array + items: + $ref: "#/$defs/reusable-action-object-parameter" + unevaluatedProperties: false + components-object: + type: object + properties: + actions: + type: object + additionalProperties: + $ref: "#/$defs/reusable-action-object" + $ref: "#/$defs/specification-extensions" + unevaluatedProperties: false info-object: type: object properties: @@ -38,7 +96,7 @@ $defs: - version $ref: "#/$defs/specification-extensions" unevaluatedProperties: false - action-object: + action-object-base: type: object properties: target: @@ -59,9 +117,13 @@ $defs: remove: type: boolean default: false + action-object: + type: object + allOf: + - $ref: "#/$defs/action-object-base" + - $ref: "#/$defs/specification-extensions" required: - target - $ref: "#/$defs/specification-extensions" unevaluatedProperties: false specification-extensions: patternProperties: diff --git a/tests/v1.2-dev/fail/action-parameter-value-invalid-type.yaml b/tests/v1.2-dev/fail/action-parameter-value-invalid-type.yaml new file mode 100644 index 0000000..a49ff4b --- /dev/null +++ b/tests/v1.2-dev/fail/action-parameter-value-invalid-type.yaml @@ -0,0 +1,20 @@ +overlay: 1.2.0 +info: + title: Reusable action reference parameter values must be strings + version: 1.0.0 +components: + actions: + errorResponse: + target: "$.paths['%param.pathItem%'].%param.operation%.responses" + update: + '404': + description: Not Found + parameters: + - name: pathItem + - name: operation + default: get +actions: + - $ref: '#/components/actions/errorResponse' + parameterValues: + pathItem: /items + operation: 100 diff --git a/tests/v1.2-dev/fail/action-with-environment-variables-invalid.yaml b/tests/v1.2-dev/fail/action-with-environment-variables-invalid.yaml new file mode 100644 index 0000000..e22b1fe --- /dev/null +++ b/tests/v1.2-dev/fail/action-with-environment-variables-invalid.yaml @@ -0,0 +1,10 @@ +overlay: 1.2.0 +info: + title: Non-reusable action objects cannot have environment variables + version: 1.0.0 +actions: + - target: '$.info' + environmentVariables: + - name: stageName + update: + description: Example diff --git a/tests/v1.2-dev/fail/action-with-parameter-invalid.yaml b/tests/v1.2-dev/fail/action-with-parameter-invalid.yaml new file mode 100644 index 0000000..3fe5a5b --- /dev/null +++ b/tests/v1.2-dev/fail/action-with-parameter-invalid.yaml @@ -0,0 +1,10 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter missing name + version: 1.0.0 +actions: + - target: '$.info' + parameters: + - default: fallback + update: + description: Updated diff --git a/tests/v1.2-dev/fail/components-actions-invalid-type.yaml b/tests/v1.2-dev/fail/components-actions-invalid-type.yaml new file mode 100644 index 0000000..a63ac20 --- /dev/null +++ b/tests/v1.2-dev/fail/components-actions-invalid-type.yaml @@ -0,0 +1,8 @@ +overlay: 1.2.0 +info: + title: Components actions must be an object + version: 1.0.0 +components: + actions: [] +actions: + - target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/components-invalid-property.yaml b/tests/v1.2-dev/fail/components-invalid-property.yaml new file mode 100644 index 0000000..5e3c27c --- /dev/null +++ b/tests/v1.2-dev/fail/components-invalid-property.yaml @@ -0,0 +1,13 @@ +overlay: 1.2.0 +info: + title: Components invalid property + version: 1.0.0 +components: + invalidProperty: true + actions: + setDescription: + target: '$.info' + update: + description: Updated +actions: + - target: '$.info' diff --git a/tests/v1.2-dev/fail/components-invalid-type.yaml b/tests/v1.2-dev/fail/components-invalid-type.yaml new file mode 100644 index 0000000..72665a4 --- /dev/null +++ b/tests/v1.2-dev/fail/components-invalid-type.yaml @@ -0,0 +1,7 @@ +overlay: 1.2.0 +info: + title: Components must be an object + version: 1.0.0 +components: [] +actions: + - target: '$' diff --git a/tests/v1.2-dev/fail/components-reusable-action-invalid-type.yaml b/tests/v1.2-dev/fail/components-reusable-action-invalid-type.yaml new file mode 100644 index 0000000..b84e519 --- /dev/null +++ b/tests/v1.2-dev/fail/components-reusable-action-invalid-type.yaml @@ -0,0 +1,9 @@ +overlay: 1.2.0 +info: + title: Components action must be an object + version: 1.0.0 +components: + actions: + brokenAction: not-an-object +actions: + - target: '$' diff --git a/tests/v1.2-dev/fail/reusable-action-environment-variable-default-invalid-type-components.yaml b/tests/v1.2-dev/fail/reusable-action-environment-variable-default-invalid-type-components.yaml new file mode 100644 index 0000000..bb60a5b --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-environment-variable-default-invalid-type-components.yaml @@ -0,0 +1,15 @@ +overlay: 1.2.0 +info: + title: Reusable action environment variable default values must be strings in components + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + environmentVariables: + - name: STAGE_NAME + default: false + update: + description: Updated +actions: + - target: '$' diff --git a/tests/v1.2-dev/fail/reusable-action-environment-variable-invalid-name-pattern.yaml b/tests/v1.2-dev/fail/reusable-action-environment-variable-invalid-name-pattern.yaml new file mode 100644 index 0000000..d55e573 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-environment-variable-invalid-name-pattern.yaml @@ -0,0 +1,17 @@ +overlay: 1.2.0 +info: + title: Reusable action environment variable name must start with a letter and be alphanumeric + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + environmentVariables: + - name: stage-name + default: dev + update: + description: Updated +actions: + - target: '$.info' + update: + description: Invalid reusable action environment variable name \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-environment-variable-invalid-name.yaml b/tests/v1.2-dev/fail/reusable-action-environment-variable-invalid-name.yaml new file mode 100644 index 0000000..9317e13 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-environment-variable-invalid-name.yaml @@ -0,0 +1,11 @@ +overlay: 1.2.0 +info: + title: Reusable action environment variable invalid name type + version: 1.0.0 +actions: + - target: '$.info' + environmentVariables: + - name: 123 + default: dev + update: + description: Updated diff --git a/tests/v1.2-dev/fail/reusable-action-environment-variables-invalid-type-components.yaml b/tests/v1.2-dev/fail/reusable-action-environment-variables-invalid-type-components.yaml new file mode 100644 index 0000000..cb3fc55 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-environment-variables-invalid-type-components.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action environment variables must be an array in components + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + environmentVariables: + name: stageName + update: + description: Example +actions: + - target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-invalid-property.yaml b/tests/v1.2-dev/fail/reusable-action-invalid-property.yaml new file mode 100644 index 0000000..f9f375f --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-invalid-property.yaml @@ -0,0 +1,13 @@ +overlay: 1.2.0 +info: + title: Reusable action invalid property + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + invalidProperty: true + update: + description: Updated +actions: + - target: '$.info' diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-default-invalid-type-components.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-default-invalid-type-components.yaml new file mode 100644 index 0000000..68ece9e --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-default-invalid-type-components.yaml @@ -0,0 +1,15 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter default values must be strings in components + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - name: titleValue + default: 100 + update: + title: Example +actions: + - target: '$' diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-invalid-name-pattern.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-invalid-name-pattern.yaml new file mode 100644 index 0000000..a412b5b --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-invalid-name-pattern.yaml @@ -0,0 +1,16 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter name must start with a letter and be alphanumeric + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - name: 1titleValue + update: + title: Example +actions: + - target: '$.info' + update: + description: Invalid reusable action parameter name \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-invalid-property.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-invalid-property.yaml new file mode 100644 index 0000000..be4cd4f --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-invalid-property.yaml @@ -0,0 +1,15 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter invalid property + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - name: titleValue + invalidProperty: true + update: + title: Example +actions: + - target: '$.info' diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-item-invalid-type.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-item-invalid-type.yaml new file mode 100644 index 0000000..77674f4 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-item-invalid-type.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter items must be objects + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - invalid + update: + title: Example +actions: + - target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-missing-name-components.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-missing-name-components.yaml new file mode 100644 index 0000000..1a1869c --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-missing-name-components.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter items must include name in components + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - default: fallback + update: + title: Example +actions: + - target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-name-invalid-type-components.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-name-invalid-type-components.yaml new file mode 100644 index 0000000..b1dd35d --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-name-invalid-type-components.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter names must be strings in components + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - name: 100 + update: + title: Example +actions: + - target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-parameter-values-not-allowed.yaml b/tests/v1.2-dev/fail/reusable-action-parameter-values-not-allowed.yaml new file mode 100644 index 0000000..1d5e536 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameter-values-not-allowed.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Parameter values are not allowed on reusable actions + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameterValues: + titleValue: Example + update: + title: '%param.titleValue%' +actions: + - $ref: '#/components/actions/setTitle' diff --git a/tests/v1.2-dev/fail/reusable-action-parameters-invalid-type-components.yaml b/tests/v1.2-dev/fail/reusable-action-parameters-invalid-type-components.yaml new file mode 100644 index 0000000..14a38d5 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-parameters-invalid-type-components.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action parameters must be an array in components + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + name: titleValue + update: + title: Example +actions: + - target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-reference-environment-variables-not-allowed.yaml b/tests/v1.2-dev/fail/reusable-action-reference-environment-variables-not-allowed.yaml new file mode 100644 index 0000000..03874c1 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-environment-variables-not-allowed.yaml @@ -0,0 +1,8 @@ +overlay: 1.2.0 +info: + title: Environment variables are not allowed on reusable action references + version: 1.0.0 +actions: + - $ref: '#/components/actions/errorResponse' + environmentVariables: + - name: stageName \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-reference-invalid-parameter-values-type.yaml b/tests/v1.2-dev/fail/reusable-action-reference-invalid-parameter-values-type.yaml new file mode 100644 index 0000000..6c71f3b --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-invalid-parameter-values-type.yaml @@ -0,0 +1,7 @@ +overlay: 1.2.0 +info: + title: Reusable action reference parameter values must be an object + version: 1.0.0 +actions: + - $ref: '#/components/actions/errorResponse' + parameterValues: [] diff --git a/tests/v1.2-dev/fail/reusable-action-reference-invalid-ref-type.yaml b/tests/v1.2-dev/fail/reusable-action-reference-invalid-ref-type.yaml new file mode 100644 index 0000000..9c95a46 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-invalid-ref-type.yaml @@ -0,0 +1,7 @@ +overlay: 1.2.0 +info: + title: Reusable action reference ref must be a string + version: 1.0.0 +actions: + - $ref: 100 + target: '$' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-reference-invalid-ref.yaml b/tests/v1.2-dev/fail/reusable-action-reference-invalid-ref.yaml new file mode 100644 index 0000000..da9c2aa --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-invalid-ref.yaml @@ -0,0 +1,7 @@ +overlay: 1.2.0 +info: + title: Reusable action reference must point to components actions + version: 1.0.0 +actions: + - $ref: '#/components/notActions/errorResponse' + target: '$.info' diff --git a/tests/v1.2-dev/fail/reusable-action-reference-parameters-not-allowed.yaml b/tests/v1.2-dev/fail/reusable-action-reference-parameters-not-allowed.yaml new file mode 100644 index 0000000..1cfebc2 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-parameters-not-allowed.yaml @@ -0,0 +1,8 @@ +overlay: 1.2.0 +info: + title: Parameters are not allowed on reusable action references + version: 1.0.0 +actions: + - $ref: '#/components/actions/errorResponse' + parameters: + - name: titleValue diff --git a/tests/v1.2-dev/fail/reusable-action-reference-unescaped-component-key.yaml b/tests/v1.2-dev/fail/reusable-action-reference-unescaped-component-key.yaml new file mode 100644 index 0000000..867f08e --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-unescaped-component-key.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action reference with unescaped component key is invalid + version: 1.0.0 +components: + actions: + 'error-response/v1~beta': + description: Adds an error response + update: + '404': + description: Not Found +actions: + - $ref: '#/components/actions/error-response/v1~beta' + target: '$.paths.*.get.responses' \ No newline at end of file diff --git a/tests/v1.2-dev/fail/reusable-action-reference-unescaped-tilde-component-key.yaml b/tests/v1.2-dev/fail/reusable-action-reference-unescaped-tilde-component-key.yaml new file mode 100644 index 0000000..0a27875 --- /dev/null +++ b/tests/v1.2-dev/fail/reusable-action-reference-unescaped-tilde-component-key.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action reference with unescaped tilde in component key is invalid + version: 1.0.0 +components: + actions: + 'error~response': + description: Adds an error response + update: + '404': + description: Not Found +actions: + - $ref: '#/components/actions/error~response' + target: '$.paths.*.get.responses' diff --git a/tests/v1.2-dev/pass/components-extensions.yaml b/tests/v1.2-dev/pass/components-extensions.yaml new file mode 100644 index 0000000..b643dc4 --- /dev/null +++ b/tests/v1.2-dev/pass/components-extensions.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Components extensions + version: 1.0.0 +components: + x-components-extension: + enabled: true + actions: + setDescription: + target: '$.info' + update: + description: Updated +actions: + - target: '$.info' diff --git a/tests/v1.2-dev/pass/components-reusable-actions.yaml b/tests/v1.2-dev/pass/components-reusable-actions.yaml new file mode 100644 index 0000000..2ab0e0a --- /dev/null +++ b/tests/v1.2-dev/pass/components-reusable-actions.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Components with reusable actions + version: 1.0.0 +components: + actions: + errorResponse: + description: Adds an error response + update: + '404': + description: Not Found +actions: + - $ref: '#/components/actions/errorResponse' + target: '$.paths.*.get.responses' diff --git a/tests/v1.2-dev/pass/reusable-action-environment-variables.yaml b/tests/v1.2-dev/pass/reusable-action-environment-variables.yaml new file mode 100644 index 0000000..0fed5bf --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-environment-variables.yaml @@ -0,0 +1,18 @@ +overlay: 1.2.0 +info: + title: Reusable action with environment variables + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + environmentVariables: + - name: STAGE_NAME + default: dev + - name: REGION_NAME + update: + description: 'Deploy stage is %env.STAGE_NAME% in %env.REGION_NAME%' +actions: + - target: '$.info' + update: + description: Reusable action environment variables are declared in components diff --git a/tests/v1.2-dev/pass/reusable-action-extensions.yaml b/tests/v1.2-dev/pass/reusable-action-extensions.yaml new file mode 100644 index 0000000..bd54ecb --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-extensions.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action extensions + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + x-action-extension: + mode: reusable + update: + description: Updated +actions: + - target: '$.info' diff --git a/tests/v1.2-dev/pass/reusable-action-parameter-extensions.yaml b/tests/v1.2-dev/pass/reusable-action-parameter-extensions.yaml new file mode 100644 index 0000000..58b5ee7 --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-parameter-extensions.yaml @@ -0,0 +1,16 @@ +overlay: 1.2.0 +info: + title: Reusable action parameter extensions + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - name: titleValue + x-parameter-extension: + source: template + update: + title: '%param.titleValue%' +actions: + - target: '$.info' diff --git a/tests/v1.2-dev/pass/reusable-action-parameters.yaml b/tests/v1.2-dev/pass/reusable-action-parameters.yaml new file mode 100644 index 0000000..9c63b9c --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-parameters.yaml @@ -0,0 +1,19 @@ +overlay: 1.2.0 +info: + title: Reusable action with parameters + version: 1.0.0 +components: + actions: + setTitle: + target: '$.info' + parameters: + - name: titleValue + - name: versionValue + default: '1' + update: + title: '%param.titleValue%' + version: '%param.versionValue%' +actions: + - target: '$.info' + update: + description: Reusable action parameters are declared in components diff --git a/tests/v1.2-dev/pass/reusable-action-reference-escaped-component-key.yaml b/tests/v1.2-dev/pass/reusable-action-reference-escaped-component-key.yaml new file mode 100644 index 0000000..30da864 --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-reference-escaped-component-key.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action reference with escaped component key + version: 1.0.0 +components: + actions: + 'error-response/v1~beta': + description: Adds an error response + update: + '404': + description: Not Found +actions: + - $ref: '#/components/actions/error-response~1v1~0beta' + target: '$.paths.*.get.responses' \ No newline at end of file diff --git a/tests/v1.2-dev/pass/reusable-action-reference-extensions.yaml b/tests/v1.2-dev/pass/reusable-action-reference-extensions.yaml new file mode 100644 index 0000000..8252f8b --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-reference-extensions.yaml @@ -0,0 +1,14 @@ +overlay: 1.2.0 +info: + title: Reusable action reference extensions + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + update: + description: Updated +actions: + - $ref: '#/components/actions/setDescription' + x-reference-extension: + applied: true diff --git a/tests/v1.2-dev/pass/reusable-action-reference-parameter-values.yaml b/tests/v1.2-dev/pass/reusable-action-reference-parameter-values.yaml new file mode 100644 index 0000000..c03c736 --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-reference-parameter-values.yaml @@ -0,0 +1,20 @@ +overlay: 1.2.0 +info: + title: Reusable action reference with parameter values + version: 1.0.0 +components: + actions: + errorResponse: + target: "$.paths['%param.pathItem%'].%param.operation%.responses" + update: + '404': + description: Not Found + parameters: + - name: pathItem + - name: operation + default: get +actions: + - $ref: '#/components/actions/errorResponse' + parameterValues: + pathItem: /items + operation: post diff --git a/tests/v1.2-dev/pass/reusable-action-reference-without-target.yaml b/tests/v1.2-dev/pass/reusable-action-reference-without-target.yaml new file mode 100644 index 0000000..67d38fa --- /dev/null +++ b/tests/v1.2-dev/pass/reusable-action-reference-without-target.yaml @@ -0,0 +1,12 @@ +overlay: 1.2.0 +info: + title: Reusable action reference without target + version: 1.0.0 +components: + actions: + setDescription: + target: '$.info' + update: + description: Updated by reusable action +actions: + - $ref: '#/components/actions/setDescription' diff --git a/versions/1.2.0-dev.md b/versions/1.2.0-dev.md index 7f771e7..fa100ab 100644 --- a/versions/1.2.0-dev.md +++ b/versions/1.2.0-dev.md @@ -84,7 +84,8 @@ This is the root object of the [Overlay](#overlay). | overlay | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the Overlay Specification that the Overlay document uses. The `overlay` field SHOULD be used by tooling to interpret the Overlay document. | | info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the Overlay. The metadata MAY be used by tooling as required. | | extends | `string` | URI reference that identifies the target document (such as an [[OpenAPI]] document) this overlay applies to. | -| actions | [[Action Object](#action-object)] | **REQUIRED** An ordered list of actions to be applied to the target document. The array MUST contain at least one value. | +| actions | [[Action Object](#action-object) or [Reusable Action Reference Object](#reusable-action-reference-object)] | **REQUIRED** An ordered list of actions to be applied to the target document. The array MUST contain at least one value. | +| components | [Components Object](#components-object) | A set of components to reuse across the Overlay Document. Optional. | This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -128,6 +129,20 @@ The metadata MAY be used by the clients if needed. This object MAY be extended with [Specification Extensions](#specification-extensions). +#### Components Object + +The object provides a set of components to be reused across the Overlay document. + +##### Fixed Fields + +| Field Name | Type | Description | +| ---- | :----: | ---- | +| actions | Map(`string`, [Reusable Action Object](#reusable-action-object)) | A key-value set of reusable actions to reference in the actions through a [Reusable Action Reference Object](#reusable-action-reference-object). Optional. | + +When a key under `components.actions` is referenced by a Reusable Action Reference Object, that key is part of a JSON Pointer token and MUST be encoded according to [[RFC6901], Section 3](https://www.rfc-editor.org/rfc/rfc6901#section-3) (for example, `~` as `~0` and `/` as `~1`). + +This object MAY be extended with [Specification Extensions](#specification-extensions). + #### Action Object This object represents one or more changes to be applied to the target document at the locations defined by the target JSONPath expression. @@ -157,6 +172,80 @@ The properties of the `update` or `copy` object MUST be compatible with the targ This object MAY be extended with [Specification Extensions](#specification-extensions). +#### Reusable Action Object + +This object defines a reusable action in `components.actions`. +It holds action fields that can be referenced from `actions` by a Reusable Action Reference Object, which MAY override those fields. +It MAY also define `parameters` and `environmentVariables` for string replacement during reference resolution. + +##### Fixed fields + +| Field Name | Type | Description | +| ---- | :----: | ---- | +| parameters | [[Reusable Action Parameter Object](#reusable-action-parameter-object)] | A list of parameters to be used during string literal replacement. Optional. | +| environmentVariables | [[Reusable Action Parameter Object](#reusable-action-parameter-object)] | A list of environment variables to be used during string literal replacement. Optional. | +| Any field defined in the [Action Object](#action-object) | mixed | The [string literal replacement syntax](#string-literal-replacement-syntax) MAY ONLY be used in string fields (`target`, `copy`) and in key or value nodes within the `update` object. It MAY NOT be used in scalar non-string fields (for example `remove`), as that would produce an invalid Overlay document according to the schema. Replacements MUST be evaluated as the reusable action reference is being resolved. | + +This object MAY be extended with [Specification Extensions](#specification-extensions). + +A reusable action is similar to an action but differs in important ways: + +1. It may omit any action field, in particular the `target` field, as these may be supplied by the [Reusable Action Reference Object](#reusable-action-reference-object). +1. String interpolation in a Reusable Action Object using variables specified in the `parameters` or `environmentVariables` fields is only allowed in string fields (`target`, `copy`) and in key or value nodes within the `update` object. It is not allowed in scalar non-string fields such as `remove`. +1. A Reusable Action Object has to be referenced by a Reusable Action Reference Object to have any effect on the OpenAPI description. + +#### Reusable Action Parameter Object + +##### Fixed fields + +| Field Name | Type | Description | +| ---- | :----: | ---- | +| name | `string` | **REQUIRED** The name of the parameter, MUST match the key for the string literal replacement expression. | +| $ref | `string` | **REQUIRED** A [same-document](https://www.rfc-editor.org/rfc/rfc3986.html#section-4.4) (or fragment-only) relative URI reference, per RFC3986 ยง4.4, and that the fragment syntax is JSON Pointer, with the pointer prefix restricted to `/components/actions/`. Component action keys in this pointer MUST be encoded according to [[RFC6901], Section 3](https://www.rfc-editor.org/rfc/rfc6901#section-3). | +| Any field defined in the [Action Object](#action-object) | mixed | Any field defined in the [Action Object](#action-object) to be used as an override to the value resolved in the reusable action. The [string literal replacement syntax](#string-literal-replacement-syntax) MAY NOT be used for any of the fields. Optional. | + +This object MAY be extended with [Specification Extensions](#specification-extensions). + +### String Literal Replacement Syntax + +The following string replacement syntax MAY be used: + +%source.key% + +Where **source** is a known source whose value MUST ONLY be **env** for environment variables, or **param** for parameters. The key MUST only contain the following characters A-Za-z0-9_, contain at least one character and start with a letter or an underscore. + +#### ABNF Notation + +```abnf +replacement-string = "%" source "." key "%" +source = "env" / "param" +key = ( ALPHA / "_" ) *( ALPHA / DIGIT / "_" ) +``` + +Where ALPHA and DIGIT rules are defined in [[RFC5234]]. + +#### Environment Replacement Source + +When the environment replacement source is used, the key MUST match (case-sensitive) an environment variable defined for the process parsing the Overlay document. If the environment variable is not defined, the processor MAY either replace it with an empty string or return an error. + +#### Parameter Replacement Source + +When the parameter replacement source is used, the key MUST match (case-sensitive) a corresponding parameter defined for the reusable action. + + ### Examples #### Structured Overlay Example @@ -559,6 +648,208 @@ paths: description: OK ``` +##### Reusable Action Reference Example - Overrides + +This example shows how a reusable action can provide shared update content while a reusable action reference overrides one or more action fields locally. In this case, each reference reuses the same error response definition but supplies a different `target` so the update is applied to different operations. + +###### Source Description + +```yaml +openapi: 3.2.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.2.0 +info: + title: Use reusable actions to insert error responses + version: 1.0.0 +components: + actions: + errorResponse: + update: + 404: + description: Not Found + application/json: + schema: + type: object + properties: + message: + type: string + target: "$.paths['placeholder'].get.response" + description: Adds an error response to the operation +actions: +- $ref: '#/components/actions/errorResponse' + # the target from the reusable action is being superseded by this local override value + target: "$.paths['items'].get.responses" +- $ref: '#/components/actions/errorResponse' + # the target from the reusable action is being superseded by this local override value + target: "$.paths['some-items'].delete.responses" +``` + +###### Result Description + +```yaml +openapi: 3.2.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + 404: + description: Not Found + application/json: + schema: + type: object + properties: + errorMessage: + type: string + /some-items: + delete: + responses: + 200: + description: OK + 404: + description: Not Found + application/json: + schema: + type: object + properties: + deleteErrorMessage: + type: string +``` + +##### Reusable Action Example - Parameters + +This example shows how a reusable action can define parameterized strings and environment-variable placeholders that are resolved separately for each reusable action reference. In this case, each reference supplies different parameter values so the same reusable action can target different operations and produce slightly different response content, while default values are used when a parameter or environment variable value is not otherwise provided. + +###### Source Description + +```yaml +openapi: 3.2.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.2.0 +info: + title: Use reusable actions to insert error responses + version: 1.0.0 +components: + actions: + errorResponse: + target: "$.paths['%param.pathItem%'].%param.operation%.responses" + update: + 404: + description: Not Found + application/json: + schema: + type: object + properties: + '%param.propertyName%': + type: string + stageName: + type: string + const: '%env.stageName%' + description: Adds an error response to the %param.pathItem% path item %param.operation% operation + parameters: + - name: pathItem + - name: operation + default: get + - name: propertyName + default: errorMessage + environmentVariables: + - name: stageName + default: dev +actions: +- $ref: '#/components/actions/errorResponse' + parameterValues: + pathItem: '/items' +- $ref: '#/components/actions/errorResponse' + parameterValues: + pathItem: '/some-items' + operation: delete + propertyName: deleteErrorMessage +``` + +> Note: in this example, no value is set for the process environment variable "stageName". + +###### Result Description + +```yaml +openapi: 3.2.0 +info: + title: Example API + version: 1.0.0 +paths: + /items: + get: + responses: + 200: + description: OK + 404: + description: Not Found + application/json: + schema: + type: object + properties: + errorMessage: + type: string + stageName: + type: string + const: dev + /some-items: + delete: + responses: + 200: + description: OK + 404: + description: Not Found + application/json: + schema: + type: object + properties: + deleteErrorMessage: + type: string + stageName: + type: string + const: dev +``` + ### Specification Extensions While the Overlay Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.