diff --git a/src/drafter.coffee b/src/drafter.coffee index c4d3ff0..b8af2c2 100644 --- a/src/drafter.coffee +++ b/src/drafter.coffee @@ -20,13 +20,17 @@ gatherPayloads = (result) -> for action in subElement.actions attributes = null + resolvedAttributes = null for actionElement in action.content attributes = actionElement if actionElement.element is 'dataStructure' + resolvedAttributes = actionElement if actionElement.element is 'resolvedDataStructure' + + resolvedAttributes ?= attributes for example in action.examples - payloads.push {payload: request, actionAttributes: attributes} for request in example.requests - payloads.push {payload: response, actionAttributes: attributes} for response in example.responses + payloads.push {payload: request, actionAttributes: resolvedAttributes} for request in example.requests + payloads.push {payload: response, actionAttributes: resolvedAttributes} for response in example.responses return payloads @@ -142,6 +146,7 @@ class Drafter # Resolve assets of a payload resolvePayload: ({payload, actionAttributes}, callback) -> attributes = null + resolvedAttributes = null contentType = '' for header in payload.headers @@ -149,12 +154,14 @@ class Drafter for element in payload.content attributes = element if element.element is 'dataStructure' + resolvedAttributes = element if element.element is 'resolvedDataStructure' - attributes ?= actionAttributes + resolvedAttributes ?= attributes + resolvedAttributes ?= actionAttributes async.waterfall [ (cb) -> - cb null, payload, attributes, contentType + cb null, payload, resolvedAttributes, contentType , generateBody , generateSchema ], (error) -> @@ -165,7 +172,8 @@ class Drafter # @param node [Object] A node of API Blueprint # @param rules [Array] List of rules to apply # @param elementTye [String] The element type of the node - expandNode: (node, rules, elementType) -> + # @param parent [Object] Parent node's content of which the current node is a part of + expandNode: (node, rules, elementType, parentContent) -> elementType ?= node.element # On root node, Gather data structures first before applying rules to any of the children nodes @@ -198,9 +206,20 @@ class Drafter dataStructure.element = 'resolvedDataStructure' @appendResolved[name].push dataStructure + # Don't expand data structures in place + if elementType is 'dataStructure' + newNode = deepcopy node + else + newNode = node + # Apply rules to the current node for rule in rules - rule[elementType].call rule, node if elementType in Object.keys(rule) + rule[elementType].call rule, newNode if elementType in Object.keys(rule) + + # Append resolved data structures + if elementType is 'dataStructure' and not deepEqual node, newNode + newNode.element = 'resolvedDataStructure' + parentContent.push newNode # Recursively do the same for children nodes switch elementType @@ -215,7 +234,7 @@ class Drafter @expandNode response, rules, 'payload' for response in node.responses if node.content and Array.isArray node.content - @expandNode element, rules for element in node.content + @expandNode element, rules, null, node.content for element in node.content # Reconstruct deprecated resource groups key from elements # diff --git a/test/fixtures/dataStructures.ast.json b/test/fixtures/dataStructures.ast.json index 9438e0c..d8261a1 100644 --- a/test/fixtures/dataStructures.ast.json +++ b/test/fixtures/dataStructures.ast.json @@ -65,6 +65,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "object", @@ -529,6 +544,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupons", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "array", @@ -558,6 +588,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon Base", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "object", @@ -754,6 +799,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "object", @@ -2552,6 +2612,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "object", @@ -3016,6 +3091,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupons", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "array", @@ -3045,6 +3135,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon Base", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "object", @@ -3241,6 +3346,21 @@ { "element": "dataStructure", "name": null, + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": null, "typeDefinition": { "typeSpecification": { "name": "object",