From 40567bd6b55aa2725b5af0309f49158ef0a5ecca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Thu, 6 Jun 2019 22:31:10 +0800 Subject: [PATCH] fix: handle array of objects properly --- src/__fixtures__/tickets.schema.json | 121 +++ src/components/SchemaRow.tsx | 7 +- .../__snapshots__/renderSchema.spec.ts.snap | 902 +++++++++++++++++- src/utils/__tests__/renderSchema.spec.ts | 1 + src/utils/renderSchema.ts | 6 +- src/utils/walk.ts | 2 +- 6 files changed, 1028 insertions(+), 11 deletions(-) create mode 100644 src/__fixtures__/tickets.schema.json diff --git a/src/__fixtures__/tickets.schema.json b/src/__fixtures__/tickets.schema.json new file mode 100644 index 00000000..adfd8218 --- /dev/null +++ b/src/__fixtures__/tickets.schema.json @@ -0,0 +1,121 @@ +{ + "type": "object", + "description": "This section allows the selection of the ticketing options for all sales of the order.", + "properties": { + "availableTicketingOptions": { + "description": "List of ticketing options of the order.", + "type": "array", + "items": { + "$ref": "../TicketingOptionInfo/TicketingOptionInfo.v1-0.yaml" + } + }, + "commonTicketingOptions": { + "type": "array", + "description": "Common ticketing options to all order items.", + "items": { + "type": "string" + } + }, + "ticketingOptionChoice": { + "type": "array", + "description": "Ticketing option selection per order item.", + "items": { + "type": "object", + "properties": { + "state": { + "description": "The status that addresses if a specific ticket option is active or not. The status active is used before ticketing or before exchange confirmation. After ticketing, the status changes in completed. This allows to store ticketing options already used at ticketing time and to clean up all non selected options after ticketing or exchanged confirmation.", + "type": "string", + "default": "ACTIVE", + "enum": [ + "COMPLETED", + "ACTIVE" + ] + }, + "orderItemBreakdown": { + "description": "Structure that contains ticketing options per order item.", + "type": "array", + "items": { + "type": "object", + "properties": { + "orderItemId": { + "type": "string", + "format": "uuid" + }, + "options": { + "description": "Available ticketing options for a given order item.", + "type": "array", + "items": { + "type": "object", + "properties": { + "title": { + "description": "Ticketing option short-description.", + "type": "string", + "readOnly": true, + "enum": [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER" + ] + }, + "selected": { + "description": "Flag to specify which ticketing option is selected. Only one option is allowed to be selected.", + "type": "boolean", + "example": true + }, + "additionalRequiredInfo": { + "description": "Additional passenger required info specific to the given ticketing option.", + "type": "string" + }, + "deliveryInfo": { + "description": "Data for ticket delivery.", + "type": "object", + "properties": { + "availableDeliveryTypes": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD" + ] + } + }, + "ticketRecipients": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY" + ] + } + }, + "ccEmail": { + "type": "string", + "format": "email" + }, + "postalAddress": { + "$ref": "../Address/Address.v0-1.yaml" + }, + "pickUpAtStation": { + "description": "The name of the Station in case you select pick up at station as a delivery type", + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/src/components/SchemaRow.tsx b/src/components/SchemaRow.tsx index f984f7ca..c3d96a66 100644 --- a/src/components/SchemaRow.tsx +++ b/src/components/SchemaRow.tsx @@ -29,7 +29,12 @@ export const SchemaRow: React.FunctionComponent = ({ node, treeStore const type = isRef(schemaNode) ? '$ref' : isCombiner(schemaNode) ? schemaNode.combiner : schemaNode.type; const description = get(schemaNode, 'annotations.description'); - const childrenCount = size(get(schemaNode, 'properties')); + const childrenCount = + type === 'object' + ? size(get(schemaNode, 'properties')) + : subtype === 'object' + ? size(get(schemaNode, 'items.properties')) + : size(get(schemaNode, 'items')); const nodeValidations = { ...('annotations' in schemaNode && schemaNode.annotations.default diff --git a/src/utils/__tests__/__snapshots__/renderSchema.spec.ts.snap b/src/utils/__tests__/__snapshots__/renderSchema.spec.ts.snap index fc13cc82..2d5fa544 100644 --- a/src/utils/__tests__/__snapshots__/renderSchema.spec.ts.snap +++ b/src/utils/__tests__/__snapshots__/renderSchema.spec.ts.snap @@ -34,6 +34,7 @@ Array [ "name": "", }, Object { + "canHaveChildren": true, "id": "random-id", "level": 1, "metadata": Object { @@ -41,7 +42,14 @@ Array [ "annotations": Object {}, "enum": undefined, "id": "random-id", - "items": undefined, + "items": Object { + "properties": Object { + "ArrayObjectProperty": Object { + "type": "string", + }, + }, + "type": "object", + }, "name": "propertyIsArrayOfObjects", "path": Array [ "properties", @@ -58,7 +66,7 @@ Array [ }, Object { "id": "random-id", - "level": 3, + "level": 2, "metadata": Object { "annotations": Object {}, "enum": undefined, @@ -89,7 +97,9 @@ Array [ "annotations": Object {}, "enum": undefined, "id": "random-id", - "items": undefined, + "items": Object { + "$ref": "./models/todo-full.json", + }, "path": Array [], "subtype": "$ref( ./models/todo-full.json )", "type": "array", @@ -509,7 +519,12 @@ Array [ }, "enum": undefined, "id": "random-id", - "items": undefined, + "items": Object { + "type": Array [ + "string", + "number", + ], + }, "name": "items", "path": Array [ "properties", @@ -671,7 +686,9 @@ Array [ "divider": "and/or", "enum": undefined, "id": "random-id", - "items": undefined, + "items": Object { + "type": "integer", + }, "path": Array [ "properties", "plan", @@ -724,7 +741,9 @@ Array [ "annotations": Object {}, "enum": undefined, "id": "random-id", - "items": undefined, + "items": Object { + "type": "integer", + }, "name": "ids", "path": Array [ "properties", @@ -869,3 +888,874 @@ Array [ }, ] `; + +exports[`renderSchema util should match tickets.schema.json 1`] = ` +Array [ + Object { + "canHaveChildren": true, + "id": "random-id", + "level": 0, + "metadata": Object { + "additionalProperties": undefined, + "annotations": Object { + "description": "This section allows the selection of the ticketing options for all sales of the order.", + }, + "enum": undefined, + "id": "random-id", + "path": Array [], + "patternProperties": undefined, + "properties": Object { + "availableTicketingOptions": Object { + "description": "List of ticketing options of the order.", + "items": Object { + "$ref": "../TicketingOptionInfo/TicketingOptionInfo.v1-0.yaml", + }, + "type": "array", + }, + "commonTicketingOptions": Object { + "description": "Common ticketing options to all order items.", + "items": Object { + "type": "string", + }, + "type": "array", + }, + "ticketingOptionChoice": Object { + "description": "Ticketing option selection per order item.", + "items": Object { + "properties": Object { + "orderItemBreakdown": Object { + "description": "Structure that contains ticketing options per order item.", + "items": Object { + "properties": Object { + "options": Object { + "description": "Available ticketing options for a given order item.", + "items": Object { + "properties": Object { + "additionalRequiredInfo": Object { + "description": "Additional passenger required info specific to the given ticketing option.", + "type": "string", + }, + "deliveryInfo": Object { + "description": "Data for ticket delivery.", + "properties": Object { + "availableDeliveryTypes": Object { + "items": Object { + "enum": Array [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD", + ], + "type": "string", + }, + "type": "array", + }, + "ccEmail": Object { + "format": "email", + "type": "string", + }, + "pickUpAtStation": Object { + "description": "The name of the Station in case you select pick up at station as a delivery type", + "type": "string", + }, + "postalAddress": Object { + "$ref": "../Address/Address.v0-1.yaml", + }, + "ticketRecipients": Object { + "items": Object { + "enum": Array [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY", + ], + "type": "string", + }, + "type": "array", + }, + }, + "type": "object", + }, + "selected": Object { + "description": "Flag to specify which ticketing option is selected. Only one option is allowed to be selected.", + "example": true, + "type": "boolean", + }, + "title": Object { + "description": "Ticketing option short-description.", + "enum": Array [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER", + ], + "readOnly": true, + "type": "string", + }, + }, + "type": "object", + }, + "type": "array", + }, + "orderItemId": Object { + "format": "uuid", + "type": "string", + }, + }, + "type": "object", + }, + "type": "array", + }, + "state": Object { + "default": "ACTIVE", + "description": "The status that addresses if a specific ticket option is active or not. The status active is used before ticketing or before exchange confirmation. After ticketing, the status changes in completed. This allows to store ticketing options already used at ticketing time and to clean up all non selected options after ticketing or exchanged confirmation.", + "enum": Array [ + "COMPLETED", + "ACTIVE", + ], + "type": "string", + }, + }, + "type": "object", + }, + "type": "array", + }, + }, + "type": "object", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 1, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object { + "description": "List of ticketing options of the order.", + }, + "enum": undefined, + "id": "random-id", + "items": Object { + "$ref": "../TicketingOptionInfo/TicketingOptionInfo.v1-0.yaml", + }, + "name": "availableTicketingOptions", + "path": Array [ + "properties", + "availableTicketingOptions", + ], + "required": false, + "subtype": "$ref( ../TicketingOptionInfo/TicketingOptionInfo.v1-0.yaml )", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 1, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object { + "description": "Common ticketing options to all order items.", + }, + "enum": undefined, + "id": "random-id", + "items": Object { + "type": "string", + }, + "name": "commonTicketingOptions", + "path": Array [ + "properties", + "commonTicketingOptions", + ], + "required": false, + "subtype": "string", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "canHaveChildren": true, + "id": "random-id", + "level": 1, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object { + "description": "Ticketing option selection per order item.", + }, + "enum": undefined, + "id": "random-id", + "items": Object { + "properties": Object { + "orderItemBreakdown": Object { + "description": "Structure that contains ticketing options per order item.", + "items": Object { + "properties": Object { + "options": Object { + "description": "Available ticketing options for a given order item.", + "items": Object { + "properties": Object { + "additionalRequiredInfo": Object { + "description": "Additional passenger required info specific to the given ticketing option.", + "type": "string", + }, + "deliveryInfo": Object { + "description": "Data for ticket delivery.", + "properties": Object { + "availableDeliveryTypes": Object { + "items": Object { + "enum": Array [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD", + ], + "type": "string", + }, + "type": "array", + }, + "ccEmail": Object { + "format": "email", + "type": "string", + }, + "pickUpAtStation": Object { + "description": "The name of the Station in case you select pick up at station as a delivery type", + "type": "string", + }, + "postalAddress": Object { + "$ref": "../Address/Address.v0-1.yaml", + }, + "ticketRecipients": Object { + "items": Object { + "enum": Array [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY", + ], + "type": "string", + }, + "type": "array", + }, + }, + "type": "object", + }, + "selected": Object { + "description": "Flag to specify which ticketing option is selected. Only one option is allowed to be selected.", + "example": true, + "type": "boolean", + }, + "title": Object { + "description": "Ticketing option short-description.", + "enum": Array [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER", + ], + "readOnly": true, + "type": "string", + }, + }, + "type": "object", + }, + "type": "array", + }, + "orderItemId": Object { + "format": "uuid", + "type": "string", + }, + }, + "type": "object", + }, + "type": "array", + }, + "state": Object { + "default": "ACTIVE", + "description": "The status that addresses if a specific ticket option is active or not. The status active is used before ticketing or before exchange confirmation. After ticketing, the status changes in completed. This allows to store ticketing options already used at ticketing time and to clean up all non selected options after ticketing or exchanged confirmation.", + "enum": Array [ + "COMPLETED", + "ACTIVE", + ], + "type": "string", + }, + }, + "type": "object", + }, + "name": "ticketingOptionChoice", + "path": Array [ + "properties", + "ticketingOptionChoice", + ], + "required": false, + "subtype": "object", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 2, + "metadata": Object { + "annotations": Object { + "default": "ACTIVE", + "description": "The status that addresses if a specific ticket option is active or not. The status active is used before ticketing or before exchange confirmation. After ticketing, the status changes in completed. This allows to store ticketing options already used at ticketing time and to clean up all non selected options after ticketing or exchanged confirmation.", + }, + "enum": Array [ + "COMPLETED", + "ACTIVE", + ], + "id": "random-id", + "name": "state", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "state", + ], + "required": false, + "type": "string", + "validations": Object { + "enum": Array [ + "COMPLETED", + "ACTIVE", + ], + }, + }, + "name": "", + }, + Object { + "canHaveChildren": true, + "id": "random-id", + "level": 2, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object { + "description": "Structure that contains ticketing options per order item.", + }, + "enum": undefined, + "id": "random-id", + "items": Object { + "properties": Object { + "options": Object { + "description": "Available ticketing options for a given order item.", + "items": Object { + "properties": Object { + "additionalRequiredInfo": Object { + "description": "Additional passenger required info specific to the given ticketing option.", + "type": "string", + }, + "deliveryInfo": Object { + "description": "Data for ticket delivery.", + "properties": Object { + "availableDeliveryTypes": Object { + "items": Object { + "enum": Array [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD", + ], + "type": "string", + }, + "type": "array", + }, + "ccEmail": Object { + "format": "email", + "type": "string", + }, + "pickUpAtStation": Object { + "description": "The name of the Station in case you select pick up at station as a delivery type", + "type": "string", + }, + "postalAddress": Object { + "$ref": "../Address/Address.v0-1.yaml", + }, + "ticketRecipients": Object { + "items": Object { + "enum": Array [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY", + ], + "type": "string", + }, + "type": "array", + }, + }, + "type": "object", + }, + "selected": Object { + "description": "Flag to specify which ticketing option is selected. Only one option is allowed to be selected.", + "example": true, + "type": "boolean", + }, + "title": Object { + "description": "Ticketing option short-description.", + "enum": Array [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER", + ], + "readOnly": true, + "type": "string", + }, + }, + "type": "object", + }, + "type": "array", + }, + "orderItemId": Object { + "format": "uuid", + "type": "string", + }, + }, + "type": "object", + }, + "name": "orderItemBreakdown", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + ], + "required": false, + "subtype": "object", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 3, + "metadata": Object { + "annotations": Object {}, + "enum": undefined, + "id": "random-id", + "name": "orderItemId", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "orderItemId", + ], + "required": false, + "type": "string", + "validations": Object { + "format": "uuid", + }, + }, + "name": "", + }, + Object { + "canHaveChildren": true, + "id": "random-id", + "level": 3, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object { + "description": "Available ticketing options for a given order item.", + }, + "enum": undefined, + "id": "random-id", + "items": Object { + "properties": Object { + "additionalRequiredInfo": Object { + "description": "Additional passenger required info specific to the given ticketing option.", + "type": "string", + }, + "deliveryInfo": Object { + "description": "Data for ticket delivery.", + "properties": Object { + "availableDeliveryTypes": Object { + "items": Object { + "enum": Array [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD", + ], + "type": "string", + }, + "type": "array", + }, + "ccEmail": Object { + "format": "email", + "type": "string", + }, + "pickUpAtStation": Object { + "description": "The name of the Station in case you select pick up at station as a delivery type", + "type": "string", + }, + "postalAddress": Object { + "$ref": "../Address/Address.v0-1.yaml", + }, + "ticketRecipients": Object { + "items": Object { + "enum": Array [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY", + ], + "type": "string", + }, + "type": "array", + }, + }, + "type": "object", + }, + "selected": Object { + "description": "Flag to specify which ticketing option is selected. Only one option is allowed to be selected.", + "example": true, + "type": "boolean", + }, + "title": Object { + "description": "Ticketing option short-description.", + "enum": Array [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER", + ], + "readOnly": true, + "type": "string", + }, + }, + "type": "object", + }, + "name": "options", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + ], + "required": false, + "subtype": "object", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 4, + "metadata": Object { + "annotations": Object { + "description": "Ticketing option short-description.", + }, + "enum": Array [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER", + ], + "id": "random-id", + "name": "title", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "title", + ], + "required": false, + "type": "string", + "validations": Object { + "enum": Array [ + "HOMEPRINT", + "TICKETLESS", + "PRINT_AT_KIOSK", + "SECURE_PAPER", + ], + }, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 4, + "metadata": Object { + "annotations": Object { + "description": "Flag to specify which ticketing option is selected. Only one option is allowed to be selected.", + }, + "enum": undefined, + "id": "random-id", + "name": "selected", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "selected", + ], + "required": false, + "type": "boolean", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 4, + "metadata": Object { + "annotations": Object { + "description": "Additional passenger required info specific to the given ticketing option.", + }, + "enum": undefined, + "id": "random-id", + "name": "additionalRequiredInfo", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "additionalRequiredInfo", + ], + "required": false, + "type": "string", + "validations": Object {}, + }, + "name": "", + }, + Object { + "canHaveChildren": true, + "id": "random-id", + "level": 4, + "metadata": Object { + "additionalProperties": undefined, + "annotations": Object { + "description": "Data for ticket delivery.", + }, + "enum": undefined, + "id": "random-id", + "name": "deliveryInfo", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "deliveryInfo", + ], + "patternProperties": undefined, + "properties": Object { + "availableDeliveryTypes": Object { + "items": Object { + "enum": Array [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD", + ], + "type": "string", + }, + "type": "array", + }, + "ccEmail": Object { + "format": "email", + "type": "string", + }, + "pickUpAtStation": Object { + "description": "The name of the Station in case you select pick up at station as a delivery type", + "type": "string", + }, + "postalAddress": Object { + "$ref": "../Address/Address.v0-1.yaml", + }, + "ticketRecipients": Object { + "items": Object { + "enum": Array [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY", + ], + "type": "string", + }, + "type": "array", + }, + }, + "required": false, + "type": "object", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 5, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object {}, + "enum": undefined, + "id": "random-id", + "items": Object { + "enum": Array [ + "POSTAL", + "PICK_UP_STATION", + "E-MAIL", + "LOYALTY_CARD", + ], + "type": "string", + }, + "name": "availableDeliveryTypes", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "deliveryInfo", + "properties", + "availableDeliveryTypes", + ], + "required": false, + "subtype": "string", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 5, + "metadata": Object { + "additionalItems": undefined, + "annotations": Object {}, + "enum": undefined, + "id": "random-id", + "items": Object { + "enum": Array [ + "BOOKER", + "CUSTOMER", + "PASSENGER", + "THIRD_PARTY", + ], + "type": "string", + }, + "name": "ticketRecipients", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "deliveryInfo", + "properties", + "ticketRecipients", + ], + "required": false, + "subtype": "string", + "type": "array", + "validations": Object {}, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 5, + "metadata": Object { + "annotations": Object {}, + "enum": undefined, + "id": "random-id", + "name": "ccEmail", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "deliveryInfo", + "properties", + "ccEmail", + ], + "required": false, + "type": "string", + "validations": Object { + "format": "email", + }, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 5, + "metadata": Object { + "$ref": "../Address/Address.v0-1.yaml", + "id": "random-id", + "name": "postalAddress", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "deliveryInfo", + "properties", + "postalAddress", + ], + "required": false, + }, + "name": "", + }, + Object { + "id": "random-id", + "level": 5, + "metadata": Object { + "annotations": Object { + "description": "The name of the Station in case you select pick up at station as a delivery type", + }, + "enum": undefined, + "id": "random-id", + "name": "pickUpAtStation", + "path": Array [ + "properties", + "ticketingOptionChoice", + "items", + "orderItemBreakdown", + "items", + "options", + "items", + "deliveryInfo", + "properties", + "pickUpAtStation", + ], + "required": false, + "type": "string", + "validations": Object {}, + }, + "name": "", + }, +] +`; diff --git a/src/utils/__tests__/renderSchema.spec.ts b/src/utils/__tests__/renderSchema.spec.ts index 06e57057..9a9bae6a 100644 --- a/src/utils/__tests__/renderSchema.spec.ts +++ b/src/utils/__tests__/renderSchema.spec.ts @@ -15,6 +15,7 @@ describe('renderSchema util', () => { ['combiner-schema.json', ''], ['array-of-objects.json', ''], ['array-of-refs.json', ''], + ['tickets.schema.json', ''], ])('should match %s', (schema, dereferenced) => { expect( Array.from(renderSchema(JSON.parse(fs.readFileSync(path.resolve(BASE_PATH, schema), 'utf-8')))), diff --git a/src/utils/renderSchema.ts b/src/utils/renderSchema.ts index 0f4fea8c..12fcf63c 100644 --- a/src/utils/renderSchema.ts +++ b/src/utils/renderSchema.ts @@ -129,7 +129,7 @@ export const renderSchema: Walker = function*(schema, level = 0, meta = { path: ...baseNode, ...('items' in node && !_isEmpty(node.items) && - !('subtype' in baseNode.metadata!) && { canHaveChildren: true }), + (baseNode.metadata!.subtype === 'object' || Array.isArray(node.items)) && { canHaveChildren: true }), metadata: { ...baseNode.metadata, // https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.3.1.2 @@ -147,13 +147,13 @@ export const renderSchema: Walker = function*(schema, level = 0, meta = { path: } else if (parsedSchema.items) { switch (baseNode.metadata && baseNode.metadata.subtype) { case SchemaKind.Object: - yield* getProperties(parsedSchema.items, level + 1, { + yield* getProperties(parsedSchema.items, level, { ...meta, path: [...path, 'items'], }); break; case SchemaKind.Array: - yield* renderSchema(parsedSchema.items, level + 1, { + yield* renderSchema(parsedSchema.items, level, { path, }); break; diff --git a/src/utils/walk.ts b/src/utils/walk.ts index b9407229..95c053a0 100644 --- a/src/utils/walk.ts +++ b/src/utils/walk.ts @@ -24,7 +24,7 @@ const getCombiner = (node: JSONSchema4): JSONSchema4CombinerName | void => { function assignNodeSpecificFields(base: IBaseNode, node: JSONSchema4) { switch (getPrimaryType(node)) { case SchemaKind.Array: - (base as IArrayNode).items = node.array; + (base as IArrayNode).items = node.items; (base as IArrayNode).additionalItems = node.additionalItems; break; case SchemaKind.Object: