diff --git a/.changeset/mean-flies-attend/changes.json b/.changeset/mean-flies-attend/changes.json new file mode 100644 index 00000000..f3490fa1 --- /dev/null +++ b/.changeset/mean-flies-attend/changes.json @@ -0,0 +1,4 @@ +{ + "releases": [{ "name": "better-ajv-errors", "type": "patch" }], + "dependents": [] +} diff --git a/.changeset/mean-flies-attend/changes.md b/.changeset/mean-flies-attend/changes.md new file mode 100644 index 00000000..92e2864a --- /dev/null +++ b/.changeset/mean-flies-attend/changes.md @@ -0,0 +1 @@ +Fix a bug where nested errors were ignored when top level had enum errors diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 71cb2854..2fe4f858 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ name: CI -on: push +on: [push, pull_request] jobs: test: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8b088c5..b280d8ba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,10 +25,8 @@ jobs: - name: Install Dependencies run: yarn install --frozen-lockfile - - name: Build - run: yarn build - - name: Publish to npm + if: github.repository == 'atlassian/better-ajv-errors' uses: changesets/action@master with: # The --otp=1 is to get around a bug in changesets diff --git a/package.json b/package.json index 2e09bd0e..e2906c3c 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,12 @@ "ajv": "4.11.8 - 6" }, "scripts": { - "clean": "rm -rf lib", - "build": "yarn run clean && yarn build:modern && yarn build:legacy", + "prebuild": "rm -rf lib", + "build": "yarn build:modern && yarn build:legacy", "build:modern": "BABEL_ENV=modern babel src -d lib/modern/", "build:legacy": "BABEL_ENV=legacy babel src -d lib/legacy", - "prepublishOnly": "yarn build", + "prerelease": "yarn build", + "release": "changeset release", "format": "prettier --write src/*.js src/**/*.js", "test": "jest", "test-ci": "jest --coverage --colors" diff --git a/src/__fixtures__/data.json b/src/__fixtures__/data.json index eee05694..6c25afd0 100644 --- a/src/__fixtures__/data.json +++ b/src/__fixtures__/data.json @@ -3,17 +3,40 @@ "type": "doc", "content": [ { - "type": "paragarph", + "type": "paragraph", + "content": [ + { + "type": "text", + "text": "test" + } + ] + }, + { + "type": "mediaSingle", + "attrs": { + "layout": "wide" + }, "content": [ { "type": "media", "attrs": { + "id": "cfb55f7b-68be-42ac-9930-216f754805a1", "type": "file", - "id": "1234", - "collection": "SampleCollection" + "collection": "", + "occurrenceKey": null, + "width": null } } ] + }, + { + "type": "paragraph", + "content": [ + { + "type": "text", + "text": " " + } + ] } ] } diff --git a/src/__fixtures__/schema.json b/src/__fixtures__/schema.json index 629e4f35..17faed2b 100644 --- a/src/__fixtures__/schema.json +++ b/src/__fixtures__/schema.json @@ -1,158 +1,81 @@ { - "description": "Schema for Atlassian Editor documents.", + "description": "Schema for Atlassian Document Format.", "$ref": "#/definitions/doc_node", "definitions": { - "panel_node": { - "type": "object", - "properties": { - "type": { "enum": ["panel"] }, - "attrs": { - "type": "object", - "properties": { - "panelType": { "enum": ["info", "note", "tip", "warning"] } - }, - "required": ["panelType"], - "additionalProperties": false - }, - "content": { "$ref": "#/definitions/top_level_node" } - }, - "required": ["type", "attrs", "content"], - "additionalProperties": false - }, - "paragraph_node": { + "em_mark": { "type": "object", "properties": { - "type": { "enum": ["paragraph"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/inline_node" } + "type": { + "enum": ["em"] } }, - "required": ["type", "content"], + "required": ["type"], "additionalProperties": false }, - "blockquote_node": { + "code_mark": { "type": "object", "properties": { - "type": { "enum": ["blockquote"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/paragraph_node" }, - "minItems": 1 + "type": { + "enum": ["code"] } }, - "required": ["type", "content"], - "additionalProperties": false - }, - "listItem_node": { - "type": "object", - "properties": { - "type": { "enum": ["listItem"] }, - "content": { "$ref": "#/definitions/top_level_node" } - }, - "required": ["type", "content"], + "required": ["type"], "additionalProperties": false }, - "orderedList_node": { + "strike_mark": { "type": "object", "properties": { - "type": { "enum": ["orderedList"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/listItem_node" }, - "minItems": 1 - }, - "attrs": { - "type": "object", - "properties": { "order": { "type": "number", "minimum": 1 } }, - "required": ["order"], - "additionalProperties": false + "type": { + "enum": ["strike"] } }, - "required": ["type", "content"], + "required": ["type"], "additionalProperties": false }, - "bulletList_node": { + "strong_mark": { "type": "object", "properties": { - "type": { "enum": ["bulletList"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/listItem_node" }, - "minItems": 1 + "type": { + "enum": ["strong"] } }, - "required": ["type", "content"], - "additionalProperties": false - }, - "rule_node": { - "type": "object", - "properties": { "type": { "enum": ["rule"] } }, "required": ["type"], "additionalProperties": false }, - "heading_node": { + "underline_mark": { "type": "object", "properties": { - "type": { "enum": ["heading"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/inline_node" } - }, - "attrs": { - "type": "object", - "properties": { - "level": { "type": "number", "minimum": 1, "maximum": 6 } - }, - "required": ["level"], - "additionalProperties": false + "type": { + "enum": ["underline"] } }, - "required": ["type", "content", "attrs"], - "additionalProperties": false - }, - "em_mark": { - "type": "object", - "properties": { "type": { "enum": ["em"] } }, - "required": ["type"], - "additionalProperties": false - }, - "code_mark": { - "type": "object", - "properties": { "type": { "enum": ["code"] } }, - "required": ["type"], - "additionalProperties": false - }, - "strike_mark": { - "type": "object", - "properties": { "type": { "enum": ["strike"] } }, - "required": ["type"], - "additionalProperties": false - }, - "strong_mark": { - "type": "object", - "properties": { "type": { "enum": ["strong"] } }, - "required": ["type"], - "additionalProperties": false - }, - "underline_mark": { - "type": "object", - "properties": { "type": { "enum": ["underline"] } }, "required": ["type"], "additionalProperties": false }, "link_mark": { "type": "object", "properties": { - "type": { "enum": ["link"] }, + "type": { + "enum": ["link"] + }, "attrs": { "type": "object", "properties": { - "href": { "type": "string" }, - "title": { "type": "string" }, - "id": { "type": "string" }, - "collection": { "type": "string" }, - "occurrenceKey": { "type": "string" } + "href": { + "type": "string" + }, + "title": { + "type": "string" + }, + "id": { + "type": "string" + }, + "collection": { + "type": "string" + }, + "occurrenceKey": { + "type": "string" + } }, "required": ["href"], "additionalProperties": false @@ -164,10 +87,16 @@ "subsup_mark": { "type": "object", "properties": { - "type": { "enum": ["subsup"] }, + "type": { + "enum": ["subsup"] + }, "attrs": { "type": "object", - "properties": { "type": { "enum": ["sub", "sup"] } }, + "properties": { + "type": { + "enum": ["sub", "sup"] + } + }, "required": ["type"], "additionalProperties": false } @@ -178,11 +107,16 @@ "textColor_mark": { "type": "object", "properties": { - "type": { "enum": ["textColor"] }, + "type": { + "enum": ["textColor"] + }, "attrs": { "type": "object", "properties": { - "color": { "type": "string", "pattern": "^#[0-9a-f]{6}$" } + "color": { + "type": "string", + "pattern": "^#[0-9a-f]{6}$" + } }, "required": ["color"], "additionalProperties": false @@ -191,33 +125,30 @@ "required": ["type", "attrs"], "additionalProperties": false }, - "inline_comment_marker": { - "type": "object", - "properties": { - "type": { "enum": ["confluenceInlineComment"] }, - "attrs": { - "type": "object", - "properties": { "reference": { "type": "string" } }, - "required": ["reference"], - "additionalProperties": false - } - }, - "required": ["type", "attrs"], - "additionalProperties": false - }, "action_mark": { "type": "object", "properties": { - "type": { "enum": ["action"] }, + "type": { + "enum": ["action"] + }, "attrs": { "type": "object", "properties": { - "title": { "type": "string" }, + "title": { + "type": "string" + }, + "key": { + "type": "string" + }, "target": { "type": "object", "properties": { - "receiver": { "type": "string" }, - "key": { "type": "string" } + "receiver": { + "type": "string" + }, + "key": { + "type": "string" + } }, "additionalProperties": false, "required": ["key"] @@ -231,683 +162,1609 @@ "required": ["type", "attrs"], "additionalProperties": false }, - "hardBreak_node": { + "breakout_mark": { "type": "object", "properties": { - "type": { "enum": ["hardBreak"] }, + "type": { + "enum": ["breakout"] + }, "attrs": { "type": "object", - "properties": { "text": { "enum": ["\n"] } }, + "properties": { + "mode": { + "enum": ["wide", "full-width"] + } + }, + "required": ["mode"], "additionalProperties": false } }, - "required": ["type"], + "required": ["type", "attrs"], "additionalProperties": false }, - "emoji_node": { + "alignment_mark": { "type": "object", "properties": { - "type": { "enum": ["emoji"] }, + "type": { + "enum": ["alignment"] + }, "attrs": { "type": "object", "properties": { - "id": { "type": "string" }, - "shortName": { "type": "string" }, - "text": { "type": "string" } + "align": { + "enum": ["center", "end"] + } }, - "additionalProperties": false, - "required": ["shortName"] + "required": ["align"], + "additionalProperties": false } }, "required": ["type", "attrs"], "additionalProperties": false }, - "mention_node": { + "indentation_mark": { "type": "object", "properties": { - "type": { "enum": ["mention"] }, + "type": { + "enum": ["indentation"] + }, "attrs": { "type": "object", "properties": { - "id": { "type": "string" }, - "text": { "type": "string" }, - "userType": { "enum": ["DEFAULT", "SPECIAL", "APP"] }, - "accessLevel": { "type": "string" } + "level": { + "type": "number", + "minimum": 1, + "maximum": 6 + } }, - "required": ["id"], + "required": ["level"], "additionalProperties": false } }, "required": ["type", "attrs"], "additionalProperties": false }, - "text_node": { - "type": "object", - "properties": { - "type": { "enum": ["text"] }, - "text": { "type": "string", "minLength": 1 }, - "marks": {} - }, - "required": ["type", "text"], - "additionalProperties": false - }, - "media_node": { + "annotation_mark": { "type": "object", "properties": { - "type": { "enum": ["media"] }, + "type": { + "enum": ["annotation"] + }, "attrs": { "type": "object", "properties": { - "id": { "type": "string", "minLength": 1 }, - "type": { "enum": ["link", "file"] }, - "collection": { "type": "string" }, - "height": { "type": "number" }, - "width": { "type": "number" }, - "occurrenceKey": { "type": "string", "minLength": 1 } - }, - "required": ["id", "type", "collection"], + "id": { + "type": "string" + }, + "annotationType": { + "enum": ["inlineComment"] + } + }, + "required": ["id", "annotationType"], "additionalProperties": false } }, "required": ["type", "attrs"], "additionalProperties": false }, - "mediaGroup_node": { + "paragraph_node": { "type": "object", "properties": { - "type": { "enum": ["mediaGroup"] }, + "type": { + "enum": ["paragraph"] + }, "content": { "type": "array", - "items": { "$ref": "#/definitions/media_node" }, - "minItems": 1 + "items": { + "$ref": "#/definitions/inline_node" + } + }, + "marks": { + "type": "array" } }, - "required": ["type", "content"], + "required": ["type"], "additionalProperties": false }, - "mediaSingle_node": { - "type": "object", - "properties": { - "type": { "enum": ["mediaSingle"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/media_node" }, - "minItems": 1, - "maxItems": 1 + "paragraph_with_no_marks_node": { + "allOf": [ + { + "$ref": "#/definitions/paragraph_node" }, - "attrs": { + { "type": "object", "properties": { - "layout": { - "enum": [ - "wrap-right", - "center", - "wrap-left", - "wide", - "full-width" - ] + "marks": { + "type": "array", + "maxItems": 0 } }, - "required": ["layout"], - "additionalProperties": false + "additionalProperties": true } - }, - "required": ["type", "content"], - "additionalProperties": false + ] }, - "table_node": { + "paragraph_with_alignment_node": { + "allOf": [ + { + "$ref": "#/definitions/paragraph_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/alignment_mark" + } + } + }, + "additionalProperties": true + } + ] + }, + "paragraph_with_indentation_node": { + "allOf": [ + { + "$ref": "#/definitions/paragraph_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/indentation_mark" + } + } + }, + "additionalProperties": true + } + ] + }, + "bulletList_node": { "type": "object", "properties": { - "type": { "enum": ["table"] }, + "type": { + "enum": ["bulletList"] + }, "content": { "type": "array", - "items": { "$ref": "#/definitions/table_row_node" }, + "items": { + "$ref": "#/definitions/listItem_node" + }, "minItems": 1 } }, "required": ["type", "content"], "additionalProperties": false }, - "table_row_node": { + "media_node": { "type": "object", "properties": { - "type": { "enum": ["tableRow"] }, - "content": { + "type": { + "enum": ["media"] + }, + "attrs": { "anyOf": [ { - "type": "array", - "items": { "$ref": "#/definitions/table_header_node" } + "type": "object", + "properties": { + "type": { + "enum": ["link", "file"] + }, + "id": { + "type": "string", + "minLength": 1 + }, + "collection": { + "type": "string" + }, + "height": { + "type": "number" + }, + "width": { + "type": "number" + }, + "occurrenceKey": { + "type": "string", + "minLength": 1 + } + }, + "required": ["type", "id", "collection"], + "additionalProperties": false }, { - "type": "array", - "items": { "$ref": "#/definitions/table_cell_node" } + "type": "object", + "properties": { + "type": { + "enum": ["external"] + }, + "url": { + "type": "string" + }, + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": ["type", "url"], + "additionalProperties": false } ] } }, - "required": ["type", "content"], + "required": ["type", "attrs"], "additionalProperties": false }, - "table_cell_node": { + "mediaSingle_node": { "type": "object", "properties": { - "type": { "enum": ["tableCell"] }, - "attrs": { - "type": "object", - "properties": { - "colspan": { "type": "number" }, - "rowspan": { "type": "number" }, - "background": { "type": "string" } - }, - "required": ["colspan", "rowspan"], + "type": { + "enum": ["mediaSingle"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/media_node" + }, + "minItems": 1, + "maxItems": 1 + }, + "attrs": { + "type": "object", + "properties": { + "width": { + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "layout": { + "enum": [ + "wide", + "full-width", + "center", + "wrap-right", + "wrap-left", + "align-end", + "align-start" + ] + } + }, + "additionalProperties": false, + "required": ["layout"] + }, + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/link_mark" + } + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "text_node": { + "type": "object", + "properties": { + "type": { + "enum": ["text"] + }, + "text": { + "type": "string", + "minLength": 1 + }, + "marks": { + "type": "array" + } + }, + "required": ["type", "text"], + "additionalProperties": false + }, + "codeBlock_node": { + "type": "object", + "properties": { + "type": { + "enum": ["codeBlock"] + }, + "content": { + "type": "array", + "items": { + "allOf": [ + { + "$ref": "#/definitions/text_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "maxItems": 0 + } + }, + "additionalProperties": true + } + ] + } + }, + "marks": { + "type": "array" + }, + "attrs": { + "type": "object", + "properties": { + "language": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "required": ["type"], + "additionalProperties": false + }, + "codeBlock_with_no_marks_node": { + "allOf": [ + { + "$ref": "#/definitions/codeBlock_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "maxItems": 0 + } + }, + "additionalProperties": true + } + ] + }, + "codeBlock_with_marks_node": { + "allOf": [ + { + "$ref": "#/definitions/codeBlock_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/breakout_mark" + } + } + }, + "additionalProperties": true + } + ] + }, + "listItem_node": { + "type": "object", + "properties": { + "type": { + "enum": ["listItem"] + }, + "content": { + "type": "array", + "items": [ + { + "anyOf": [ + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/mediaSingle_node" + }, + { + "$ref": "#/definitions/codeBlock_with_no_marks_node" + } + ] + }, + { + "anyOf": [ + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/bulletList_node" + }, + { + "$ref": "#/definitions/mediaSingle_node" + }, + { + "$ref": "#/definitions/codeBlock_with_no_marks_node" + }, + { + "$ref": "#/definitions/orderedList_node" + } + ] + } + ], + "minItems": 1 + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "orderedList_node": { + "type": "object", + "properties": { + "type": { + "enum": ["orderedList"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/listItem_node" + }, + "minItems": 1 + }, + "attrs": { + "type": "object", + "properties": { + "order": { + "type": "number", + "minimum": 1 + } + }, + "required": ["order"], + "additionalProperties": false + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "heading_node": { + "type": "object", + "properties": { + "type": { + "enum": ["heading"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/inline_node" + } + }, + "marks": { + "type": "array" + }, + "attrs": { + "type": "object", + "properties": { + "level": { + "type": "number", + "minimum": 1, + "maximum": 6 + } + }, + "required": ["level"], + "additionalProperties": false + } + }, + "required": ["type", "attrs"], + "additionalProperties": false + }, + "heading_with_no_marks_node": { + "allOf": [ + { + "$ref": "#/definitions/heading_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "maxItems": 0 + } + }, + "additionalProperties": true + } + ] + }, + "heading_with_alignment_node": { + "allOf": [ + { + "$ref": "#/definitions/heading_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/alignment_mark" + } + } + }, + "additionalProperties": true + } + ] + }, + "heading_with_indentation_node": { + "allOf": [ + { + "$ref": "#/definitions/heading_node" + }, + { + "type": "object", + "properties": { + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/indentation_mark" + } + } + }, + "additionalProperties": true + } + ] + }, + "panel_node": { + "type": "object", + "properties": { + "type": { + "enum": ["panel"] + }, + "attrs": { + "type": "object", + "properties": { + "panelType": { + "enum": ["info", "note", "tip", "warning", "error", "success"] + } + }, + "required": ["panelType"], + "additionalProperties": false + }, + "content": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/bulletList_node" + }, + { + "$ref": "#/definitions/orderedList_node" + }, + { + "$ref": "#/definitions/heading_with_no_marks_node" + } + ] + }, + "minItems": 1 + } + }, + "required": ["type", "attrs", "content"], + "additionalProperties": false + }, + "blockquote_node": { + "type": "object", + "properties": { + "type": { + "enum": ["blockquote"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + "minItems": 1 + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "rule_node": { + "type": "object", + "properties": { + "type": { + "enum": ["rule"] + } + }, + "required": ["type"], + "additionalProperties": false + }, + "mediaGroup_node": { + "type": "object", + "properties": { + "type": { + "enum": ["mediaGroup"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/media_node" + }, + "minItems": 1 + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "applicationCard_node": { + "type": "object", + "properties": { + "type": { + "enum": ["applicationCard"] + }, + "attrs": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "textUrl": { + "type": "string" + }, + "link": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https?://|^data:image/" + } + }, + "required": ["url"], + "additionalProperties": false + }, + "background": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https://|^data:image/" + } + }, + "required": ["url"], + "additionalProperties": false + }, + "collapsible": { + "type": "boolean" + }, + "preview": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https://|^data:image/" + } + }, + "required": ["url"], + "additionalProperties": false + }, + "title": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "icon": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https://|^data:image/" + }, + "label": { + "type": "string" + } + }, + "required": ["url", "label"], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["icon"] + } + }, + "required": ["text"], + "additionalProperties": false + }, + "description": { + "type": "object", + "properties": { + "text": { + "type": "string" + } + }, + "required": ["text"], + "additionalProperties": false + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "text": { + "type": "string" + }, + "icon": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https://|^data:image/" + }, + "label": { + "type": "string" + } + }, + "required": ["url", "label"], + "additionalProperties": false + }, + "badge": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "max": { + "type": "number" + }, + "theme": { + "enum": ["default", "dark"] + }, + "appearance": { + "enum": [ + "default", + "primary", + "important", + "added", + "removed" + ] + } + }, + "required": ["value"], + "additionalProperties": false + }, + "lozenge": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "bold": { + "type": "boolean" + }, + "appearance": { + "enum": [ + "success", + "default", + "removed", + "inprogress", + "new", + "moved" + ] + } + }, + "required": ["text"], + "additionalProperties": false + }, + "users": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "icon": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https://|^data:image/" + }, + "label": { + "type": "string" + } + }, + "required": ["url", "label"], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["icon"] + } + } + }, + "additionalProperties": false + } + }, + "actions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "title": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "receiver": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["key"] + }, + "parameters": {} + }, + "additionalProperties": false, + "required": ["title", "target"] + } + }, + "context": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "icon": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^https://|^data:image/" + }, + "label": { + "type": "string" + } + }, + "required": ["url", "label"], + "additionalProperties": false + } + }, + "required": ["text"], + "additionalProperties": false + } + }, + "required": ["text", "title"], + "additionalProperties": false + } + }, + "required": ["type", "attrs"], + "additionalProperties": false + }, + "decisionItem_node": { + "type": "object", + "properties": { + "type": { + "enum": ["decisionItem"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/inline_node" + } + }, + "attrs": { + "type": "object", + "properties": { + "localId": { + "type": "string" + }, + "state": { + "type": "string" + } + }, + "required": ["localId", "state"], + "additionalProperties": false + } + }, + "required": ["type", "attrs"], + "additionalProperties": false + }, + "decisionList_node": { + "type": "object", + "properties": { + "type": { + "enum": ["decisionList"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/decisionItem_node" + }, + "minItems": 1 + }, + "attrs": { + "type": "object", + "properties": { + "localId": { + "type": "string" + } + }, + "required": ["localId"], + "additionalProperties": false + } + }, + "required": ["type", "content", "attrs"], + "additionalProperties": false + }, + "taskItem_node": { + "type": "object", + "properties": { + "type": { + "enum": ["taskItem"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/inline_node" + } + }, + "attrs": { + "type": "object", + "properties": { + "localId": { + "type": "string" + }, + "state": { + "enum": ["TODO", "DONE"] + } + }, + "required": ["localId", "state"], + "additionalProperties": false + } + }, + "required": ["type", "attrs"], + "additionalProperties": false + }, + "taskList_node": { + "type": "object", + "properties": { + "type": { + "enum": ["taskList"] + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/taskItem_node" + }, + "minItems": 1 + }, + "attrs": { + "type": "object", + "properties": { + "localId": { + "type": "string" + } + }, + "required": ["localId"], + "additionalProperties": false + } + }, + "required": ["type", "content", "attrs"], + "additionalProperties": false + }, + "table_node": { + "type": "object", + "properties": { + "type": { + "enum": ["table"] + }, + "attrs": { + "type": "object", + "properties": { + "isNumberColumnEnabled": { + "type": "boolean" + }, + "layout": { + "enum": ["wide", "full-width", "default"] + } + }, + "additionalProperties": false + }, + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/table_row_node" + }, + "minItems": 1 + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "table_row_node": { + "type": "object", + "properties": { + "type": { + "enum": ["tableRow"] + }, + "content": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/table_cell_node" + }, + { + "$ref": "#/definitions/table_header_node" + } + ] + } + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "table_cell_node": { + "type": "object", + "properties": { + "type": { + "enum": ["tableCell"] + }, + "attrs": { + "type": "object", + "properties": { + "colspan": { + "type": "number" + }, + "rowspan": { + "type": "number" + }, + "colwidth": { + "type": "array", + "items": { + "type": "number" + } + }, + "background": { + "type": "string" + } + }, + "additionalProperties": false + }, + "content": { + "$ref": "#/definitions/table_cell_content" + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "table_header_node": { + "type": "object", + "properties": { + "type": { + "enum": ["tableHeader"] + }, + "attrs": { + "type": "object", + "properties": { + "colspan": { + "type": "number" + }, + "rowspan": { + "type": "number" + }, + "colwidth": { + "type": "array", + "items": { + "type": "number" + } + }, + "background": { + "type": "string" + } + }, + "additionalProperties": false + }, + "content": { + "$ref": "#/definitions/table_cell_content" + } + }, + "required": ["type", "content"], + "additionalProperties": false + }, + "extension_node": { + "type": "object", + "properties": { + "type": { + "enum": ["extension"] + }, + "attrs": { + "type": "object", + "properties": { + "extensionKey": { + "type": "string", + "minLength": 1 + }, + "extensionType": { + "type": "string", + "minLength": 1 + }, + "parameters": {}, + "text": { + "type": "string" + }, + "layout": { + "enum": ["wide", "full-width", "default"] + } + }, + "required": ["extensionKey", "extensionType"], + "additionalProperties": false + } + }, + "required": ["type", "attrs"], + "additionalProperties": false + }, + "inlineExtension_node": { + "type": "object", + "properties": { + "type": { + "enum": ["inlineExtension"] + }, + "attrs": { + "type": "object", + "properties": { + "extensionKey": { + "type": "string", + "minLength": 1 + }, + "extensionType": { + "type": "string", + "minLength": 1 + }, + "parameters": {}, + "text": { + "type": "string" + } + }, + "required": ["extensionKey", "extensionType"], "additionalProperties": false - }, - "content": { "$ref": "#/definitions/table_cell_content" } + } }, - "required": ["type", "attrs", "content"], + "required": ["type", "attrs"], "additionalProperties": false }, - "table_header_node": { + "bodiedExtension_node": { "type": "object", "properties": { - "type": { "enum": ["tableHeader"] }, + "type": { + "enum": ["bodiedExtension"] + }, "attrs": { "type": "object", "properties": { - "colspan": { "type": "number" }, - "rowspan": { "type": "number" }, - "background": { "type": "string" } + "extensionKey": { + "type": "string", + "minLength": 1 + }, + "extensionType": { + "type": "string", + "minLength": 1 + }, + "parameters": {}, + "text": { + "type": "string" + }, + "layout": { + "enum": ["wide", "full-width", "default"] + } }, - "required": ["colspan", "rowspan"], + "required": ["extensionKey", "extensionType"], "additionalProperties": false }, - "content": { "$ref": "#/definitions/table_cell_content" } + "content": { + "$ref": "#/definitions/extension_content" + } }, "required": ["type", "attrs", "content"], "additionalProperties": false }, - "applicationCard_node": { + "hardBreak_node": { "type": "object", "properties": { - "type": { "enum": ["applicationCard"] }, + "type": { + "enum": ["hardBreak"] + }, "attrs": { "type": "object", "properties": { - "text": { "type": "string" }, - "textUrl": { "type": "string" }, - "link": { - "type": "object", - "properties": { - "url": { "type": "string", "pattern": "^https://|^data:image/" } - }, - "required": ["url"], - "additionalProperties": false - }, - "background": { - "type": "object", - "properties": { - "url": { "type": "string", "pattern": "^https://|^data:image/" } - }, - "required": ["url"], - "additionalProperties": false - }, - "collapsible": { "type": "boolean" }, - "preview": { - "type": "object", - "properties": { - "url": { "type": "string", "pattern": "^https://|^data:image/" } - }, - "required": ["url"], - "additionalProperties": false - }, - "title": { - "type": "object", - "properties": { - "text": { "type": "string" }, - "user": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "icon": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^https://|^data:image/" - }, - "label": { "type": "string" } - }, - "required": ["url", "label"], - "additionalProperties": false - } - }, - "additionalProperties": false, - "required": ["icon"] - } - }, - "required": ["text"], - "additionalProperties": false - }, - "description": { - "type": "object", - "properties": { "text": { "type": "string" } }, - "required": ["text"], - "additionalProperties": false - }, - "details": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { "type": "string" }, - "text": { "type": "string" }, - "icon": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^https://|^data:image/" - }, - "label": { "type": "string" } - }, - "required": ["url", "label"], - "additionalProperties": false - }, - "badge": { - "type": "object", - "properties": { - "value": { "type": "number" }, - "max": { "type": "number" }, - "theme": { "enum": ["default", "dark"] }, - "appearance": { - "enum": [ - "default", - "primary", - "important", - "added", - "removed" - ] - } - }, - "required": ["value"], - "additionalProperties": false - }, - "lozenge": { - "type": "object", - "properties": { - "text": { "type": "string" }, - "bold": { "type": "boolean" }, - "appearance": { - "enum": [ - "default", - "removed", - "success", - "inprogress", - "new", - "moved" - ] - } - }, - "required": ["text"], - "additionalProperties": false - }, - "users": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "icon": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^https://|^data:image/" - }, - "label": { "type": "string" } - }, - "required": ["url", "label"], - "additionalProperties": false - } - }, - "additionalProperties": false, - "required": ["icon"] - } - } - }, - "additionalProperties": false - } - }, - "actions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { "type": "string" }, - "target": { - "type": "object", - "properties": { - "receiver": { "type": "string" }, - "key": { "type": "string" } - }, - "additionalProperties": false, - "required": ["key"] - }, - "parameters": {} - }, - "required": ["title", "target"], - "additionalProperties": false - } - }, - "context": { - "type": "object", - "properties": { - "text": { "type": "string" }, - "icon": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^https://|^data:image/" - }, - "label": { "type": "string" } - }, - "required": ["url", "label"], - "additionalProperties": false - } - }, - "required": ["text"], - "additionalProperties": false + "text": { + "enum": ["\n"] } }, - "required": ["text", "title"], "additionalProperties": false } }, - "required": ["type", "attrs"], + "required": ["type"], "additionalProperties": false }, - "decisionItem_node": { + "mention_node": { "type": "object", "properties": { - "type": { "enum": ["decisionItem"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/inline_node" } + "type": { + "enum": ["mention"] }, "attrs": { "type": "object", "properties": { - "localId": { "type": "string" }, - "state": { "type": "string" } + "id": { + "type": "string" + }, + "text": { + "type": "string" + }, + "userType": { + "enum": ["DEFAULT", "SPECIAL", "APP"] + }, + "accessLevel": { + "type": "string" + } }, - "required": ["localId", "state"], + "required": ["id"], "additionalProperties": false } }, - "required": ["type", "content", "attrs"], + "required": ["type", "attrs"], "additionalProperties": false }, - "decisionList_node": { + "emoji_node": { "type": "object", "properties": { - "type": { "enum": ["decisionList"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/decisionItem_node" }, - "minItems": 1 + "type": { + "enum": ["emoji"] }, "attrs": { "type": "object", - "properties": { "localId": { "type": "string" } }, - "required": ["localId"], - "additionalProperties": false + "properties": { + "id": { + "type": "string" + }, + "shortName": { + "type": "string" + }, + "text": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["shortName"] } }, - "required": ["type", "content", "attrs"], + "required": ["type", "attrs"], "additionalProperties": false }, - "taskItem_node": { + "date_node": { "type": "object", "properties": { - "type": { "enum": ["taskItem"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/inline_node" } + "type": { + "enum": ["date"] }, "attrs": { "type": "object", "properties": { - "localId": { "type": "string" }, - "state": { "enum": ["TODO", "DONE"] } + "timestamp": { + "type": "string", + "minLength": 1 + } }, - "required": ["localId", "state"], + "required": ["timestamp"], "additionalProperties": false } }, - "required": ["type", "content", "attrs"], + "required": ["type", "attrs"], "additionalProperties": false }, - "taskList_node": { + "status_node": { "type": "object", "properties": { - "type": { "enum": ["taskList"] }, - "content": { - "type": "array", - "items": { "$ref": "#/definitions/taskItem_node" }, - "minItems": 1 + "type": { + "enum": ["status"] }, "attrs": { "type": "object", - "properties": { "localId": { "type": "string" } }, - "required": ["localId"], + "properties": { + "text": { + "type": "string", + "minLength": 1 + }, + "color": { + "enum": ["neutral", "purple", "blue", "red", "yellow", "green"] + }, + "localId": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "required": ["text", "color"], "additionalProperties": false } }, - "required": ["type", "content", "attrs"], + "required": ["type", "attrs"], "additionalProperties": false }, - "extension_node": { + "placeholder_node": { "type": "object", "properties": { - "type": { "enum": ["extension"] }, + "type": { + "enum": ["placeholder"] + }, "attrs": { "type": "object", "properties": { - "extensionKey": { "type": "string", "minLength": 1 }, - "extensionType": { "type": "string", "minLength": 1 }, - "parameters": {}, - "text": { "type": "string" } + "text": { + "type": "string" + } }, - "required": ["extensionKey", "extensionType"], + "required": ["text"], "additionalProperties": false } }, "required": ["type", "attrs"], "additionalProperties": false }, - "inlineExtension_node": { + "blockCard_node": { + "type": "object", + "properties": { + "type": { + "enum": ["blockCard"] + }, + "attrs": { + "anyOf": [ + { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "data": {} + }, + "required": ["data"], + "additionalProperties": false + } + ] + } + }, + "required": ["type", "attrs"], + "additionalProperties": false + }, + "inlineCard_node": { "type": "object", "properties": { - "type": { "enum": ["inlineExtension"] }, + "type": { + "enum": ["inlineCard"] + }, "attrs": { - "type": "object", - "properties": { - "extensionKey": { "type": "string", "minLength": 1 }, - "extensionType": { "type": "string", "minLength": 1 }, - "parameters": {}, - "text": { "type": "string" } - }, - "required": ["extensionKey", "extensionType"], - "additionalProperties": false + "anyOf": [ + { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "data": {} + }, + "required": ["data"], + "additionalProperties": false + } + ] } }, "required": ["type", "attrs"], "additionalProperties": false }, - "bodiedExtension_node": { + "layoutColumn_node": { "type": "object", "properties": { - "type": { "enum": ["bodiedExtension"] }, + "type": { + "enum": ["layoutColumn"] + }, "attrs": { "type": "object", "properties": { - "extensionKey": { "type": "string", "minLength": 1 }, - "extensionType": { "type": "string", "minLength": 1 }, - "parameters": {}, - "text": { "type": "string" } + "width": { + "type": "number", + "minimum": 0, + "maximum": 100 + } }, - "required": ["extensionKey", "extensionType"], + "required": ["width"], "additionalProperties": false }, - "content": { "$ref": "#/definitions/extension_content" } + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/block_content" + }, + "minItems": 1 + } }, "required": ["type", "attrs", "content"], "additionalProperties": false }, - "codeBlock_node": { + "layoutSection_node": { "type": "object", "properties": { - "type": { "enum": ["codeBlock"] }, + "type": { + "enum": ["layoutSection"] + }, "content": { "type": "array", "items": { - "allOf": [ - { "$ref": "#/definitions/text_node" }, - { - "type": "object", - "properties": { "marks": { "type": "array", "maxItems": 0 } }, - "additionalProperties": true - } - ] - } - }, - "attrs": { - "type": "object", - "properties": { - "language": { - "enum": [ - "abap", - "actionscript", - "ada", - "arduino", - "autoit", - "c", - "c++", - "clojure", - "coffeescript", - "csharp", - "css", - "cuda", - "d", - "dart", - "delphi", - "elixir", - "erlang", - "fortran", - "foxpro", - "go", - "groovy", - "haskell", - "haxe", - "html", - "java", - "javascript", - "json", - "julia", - "kotlin", - "latex", - "livescript", - "lua", - "mathematica", - "matlab", - "objective-c", - "objective-j", - "objectpascal", - "ocaml", - "octave", - "perl", - "php", - "powershell", - "prolog", - "puppet", - "python", - "qml", - "r", - "racket", - "restructuredtext", - "ruby", - "rust", - "sass", - "scala", - "scheme", - "shell", - "smalltalk", - "sql", - "standardml", - "swift", - "tcl", - "tex", - "typescript", - "vala", - "vbnet", - "verilog", - "vhdl", - "xml", - "xquery" - ] - } + "$ref": "#/definitions/layoutColumn_node" }, - "additionalProperties": false + "minItems": 2, + "maxItems": 3 + }, + "marks": { + "type": "array", + "items": { + "$ref": "#/definitions/breakout_mark" + } } }, - "required": ["type"], + "required": ["type", "content"], "additionalProperties": false }, - "top_level_node": { - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/panel_node" }, - { "$ref": "#/definitions/paragraph_node" }, - { "$ref": "#/definitions/blockquote_node" }, - { "$ref": "#/definitions/orderedList_node" }, - { "$ref": "#/definitions/bulletList_node" }, - { "$ref": "#/definitions/rule_node" }, - { "$ref": "#/definitions/heading_node" }, - { "$ref": "#/definitions/mediaGroup_node" }, - { "$ref": "#/definitions/mediaSingle_node" }, - { "$ref": "#/definitions/table_node" }, - { "$ref": "#/definitions/applicationCard_node" }, - { "$ref": "#/definitions/decisionList_node" }, - { "$ref": "#/definitions/taskList_node" }, - { "$ref": "#/definitions/extension_node" }, - { "$ref": "#/definitions/bodiedExtension_node" }, - { "$ref": "#/definitions/codeBlock_node" } - ] - }, - "minItems": 1 + "block_content": { + "anyOf": [ + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/paragraph_with_alignment_node" + }, + { + "$ref": "#/definitions/paragraph_with_indentation_node" + }, + { + "$ref": "#/definitions/bulletList_node" + }, + { + "$ref": "#/definitions/mediaSingle_node" + }, + { + "$ref": "#/definitions/codeBlock_with_no_marks_node" + }, + { + "$ref": "#/definitions/orderedList_node" + }, + { + "$ref": "#/definitions/heading_with_no_marks_node" + }, + { + "$ref": "#/definitions/heading_with_alignment_node" + }, + { + "$ref": "#/definitions/heading_with_indentation_node" + }, + { + "$ref": "#/definitions/panel_node" + }, + { + "$ref": "#/definitions/blockquote_node" + }, + { + "$ref": "#/definitions/rule_node" + }, + { + "$ref": "#/definitions/mediaGroup_node" + }, + { + "$ref": "#/definitions/applicationCard_node" + }, + { + "$ref": "#/definitions/decisionList_node" + }, + { + "$ref": "#/definitions/taskList_node" + }, + { + "$ref": "#/definitions/table_node" + }, + { + "$ref": "#/definitions/extension_node" + }, + { + "$ref": "#/definitions/bodiedExtension_node" + }, + { + "$ref": "#/definitions/blockCard_node" + } + ] }, "table_cell_content": { "type": "array", "items": { "anyOf": [ - { "$ref": "#/definitions/panel_node" }, - { "$ref": "#/definitions/paragraph_node" }, - { "$ref": "#/definitions/blockquote_node" }, - { "$ref": "#/definitions/orderedList_node" }, - { "$ref": "#/definitions/bulletList_node" }, - { "$ref": "#/definitions/rule_node" }, - { "$ref": "#/definitions/heading_node" }, - { "$ref": "#/definitions/mediaGroup_node" }, - { "$ref": "#/definitions/mediaSingle_node" }, - { "$ref": "#/definitions/applicationCard_node" }, - { "$ref": "#/definitions/decisionList_node" }, - { "$ref": "#/definitions/taskList_node" }, - { "$ref": "#/definitions/extension_node" }, - { "$ref": "#/definitions/inlineExtension_node" }, - { "$ref": "#/definitions/bodiedExtension_node" }, - { "$ref": "#/definitions/codeBlock_node" } + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/paragraph_with_alignment_node" + }, + { + "$ref": "#/definitions/paragraph_with_indentation_node" + }, + { + "$ref": "#/definitions/bulletList_node" + }, + { + "$ref": "#/definitions/mediaSingle_node" + }, + { + "$ref": "#/definitions/codeBlock_with_no_marks_node" + }, + { + "$ref": "#/definitions/orderedList_node" + }, + { + "$ref": "#/definitions/heading_with_no_marks_node" + }, + { + "$ref": "#/definitions/heading_with_alignment_node" + }, + { + "$ref": "#/definitions/heading_with_indentation_node" + }, + { + "$ref": "#/definitions/panel_node" + }, + { + "$ref": "#/definitions/blockquote_node" + }, + { + "$ref": "#/definitions/rule_node" + }, + { + "$ref": "#/definitions/mediaGroup_node" + }, + { + "$ref": "#/definitions/applicationCard_node" + }, + { + "$ref": "#/definitions/decisionList_node" + }, + { + "$ref": "#/definitions/taskList_node" + }, + { + "$ref": "#/definitions/extension_node" + }, + { + "$ref": "#/definitions/blockCard_node" + } ] }, "minItems": 1 @@ -916,28 +1773,63 @@ "type": "array", "items": { "anyOf": [ - { "$ref": "#/definitions/panel_node" }, - { "$ref": "#/definitions/paragraph_node" }, - { "$ref": "#/definitions/blockquote_node" }, - { "$ref": "#/definitions/orderedList_node" }, - { "$ref": "#/definitions/bulletList_node" }, - { "$ref": "#/definitions/rule_node" }, - { "$ref": "#/definitions/heading_node" }, - { "$ref": "#/definitions/mediaGroup_node" }, - { "$ref": "#/definitions/mediaSingle_node" }, - { "$ref": "#/definitions/table_node" }, - { "$ref": "#/definitions/applicationCard_node" }, - { "$ref": "#/definitions/decisionList_node" }, - { "$ref": "#/definitions/taskList_node" }, - { "$ref": "#/definitions/inlineExtension_node" }, - { "$ref": "#/definitions/codeBlock_node" } + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/bulletList_node" + }, + { + "$ref": "#/definitions/mediaSingle_node" + }, + { + "$ref": "#/definitions/codeBlock_with_no_marks_node" + }, + { + "$ref": "#/definitions/orderedList_node" + }, + { + "$ref": "#/definitions/heading_with_no_marks_node" + }, + { + "$ref": "#/definitions/panel_node" + }, + { + "$ref": "#/definitions/blockquote_node" + }, + { + "$ref": "#/definitions/rule_node" + }, + { + "$ref": "#/definitions/mediaGroup_node" + }, + { + "$ref": "#/definitions/applicationCard_node" + }, + { + "$ref": "#/definitions/decisionList_node" + }, + { + "$ref": "#/definitions/taskList_node" + }, + { + "$ref": "#/definitions/table_node" + }, + { + "$ref": "#/definitions/extension_node" + }, + { + "$ref": "#/definitions/blockCard_node" + } ] }, "minItems": 1 }, "formatted_text_inline_node": { "allOf": [ - { "$ref": "#/definitions/text_node" }, + { + "$ref": "#/definitions/text_node" + }, { "type": "object", "properties": { @@ -945,14 +1837,33 @@ "type": "array", "items": { "anyOf": [ - { "$ref": "#/definitions/em_mark" }, - { "$ref": "#/definitions/strike_mark" }, - { "$ref": "#/definitions/strong_mark" }, - { "$ref": "#/definitions/underline_mark" }, - { "$ref": "#/definitions/link_mark" }, - { "$ref": "#/definitions/subsup_mark" }, - { "$ref": "#/definitions/textColor_mark" }, - { "$ref": "#/definitions/action_mark" } + { + "$ref": "#/definitions/em_mark" + }, + { + "$ref": "#/definitions/strike_mark" + }, + { + "$ref": "#/definitions/strong_mark" + }, + { + "$ref": "#/definitions/underline_mark" + }, + { + "$ref": "#/definitions/link_mark" + }, + { + "$ref": "#/definitions/subsup_mark" + }, + { + "$ref": "#/definitions/textColor_mark" + }, + { + "$ref": "#/definitions/action_mark" + }, + { + "$ref": "#/definitions/annotation_mark" + } ] } } @@ -961,24 +1872,11 @@ } ] }, - "link_text_inline_node": { - "allOf": [ - { "$ref": "#/definitions/text_node" }, - { - "type": "object", - "properties": { - "marks": { - "type": "array", - "items": { "$ref": "#/definitions/link_mark" } - } - }, - "additionalProperties": true - } - ] - }, "code_inline_node": { "allOf": [ - { "$ref": "#/definitions/text_node" }, + { + "$ref": "#/definitions/text_node" + }, { "type": "object", "properties": { @@ -986,8 +1884,15 @@ "type": "array", "items": { "anyOf": [ - { "$ref": "#/definitions/code_mark" }, - { "$ref": "#/definitions/link_mark" } + { + "$ref": "#/definitions/code_mark" + }, + { + "$ref": "#/definitions/link_mark" + }, + { + "$ref": "#/definitions/annotation_mark" + } ] } } @@ -996,30 +1901,125 @@ } ] }, - "atomic_inline_node": { - "anyOf": [ - { "$ref": "#/definitions/hardBreak_node" }, - { "$ref": "#/definitions/emoji_node" }, - { "$ref": "#/definitions/mention_node" }, - { "$ref": "#/definitions/inlineExtension_node" } - ] - }, "inline_node": { "anyOf": [ - { "$ref": "#/definitions/hardBreak_node" }, - { "$ref": "#/definitions/emoji_node" }, - { "$ref": "#/definitions/mention_node" }, - { "$ref": "#/definitions/inlineExtension_node" }, - { "$ref": "#/definitions/formatted_text_inline_node" }, - { "$ref": "#/definitions/code_inline_node" } + { + "$ref": "#/definitions/inlineExtension_node" + }, + { + "$ref": "#/definitions/hardBreak_node" + }, + { + "$ref": "#/definitions/mention_node" + }, + { + "$ref": "#/definitions/emoji_node" + }, + { + "$ref": "#/definitions/date_node" + }, + { + "$ref": "#/definitions/status_node" + }, + { + "$ref": "#/definitions/placeholder_node" + }, + { + "$ref": "#/definitions/inlineCard_node" + }, + { + "$ref": "#/definitions/formatted_text_inline_node" + }, + { + "$ref": "#/definitions/code_inline_node" + } ] }, "doc_node": { "type": "object", "properties": { - "version": { "enum": [1] }, - "type": { "enum": ["doc"] }, - "content": { "$ref": "#/definitions/top_level_node" } + "version": { + "enum": [1] + }, + "type": { + "enum": ["doc"] + }, + "content": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/paragraph_with_no_marks_node" + }, + { + "$ref": "#/definitions/paragraph_with_alignment_node" + }, + { + "$ref": "#/definitions/paragraph_with_indentation_node" + }, + { + "$ref": "#/definitions/bulletList_node" + }, + { + "$ref": "#/definitions/mediaSingle_node" + }, + { + "$ref": "#/definitions/codeBlock_with_no_marks_node" + }, + { + "$ref": "#/definitions/codeBlock_with_marks_node" + }, + { + "$ref": "#/definitions/orderedList_node" + }, + { + "$ref": "#/definitions/heading_with_no_marks_node" + }, + { + "$ref": "#/definitions/heading_with_alignment_node" + }, + { + "$ref": "#/definitions/heading_with_indentation_node" + }, + { + "$ref": "#/definitions/panel_node" + }, + { + "$ref": "#/definitions/blockquote_node" + }, + { + "$ref": "#/definitions/rule_node" + }, + { + "$ref": "#/definitions/mediaGroup_node" + }, + { + "$ref": "#/definitions/applicationCard_node" + }, + { + "$ref": "#/definitions/decisionList_node" + }, + { + "$ref": "#/definitions/taskList_node" + }, + { + "$ref": "#/definitions/table_node" + }, + { + "$ref": "#/definitions/extension_node" + }, + { + "$ref": "#/definitions/bodiedExtension_node" + }, + { + "$ref": "#/definitions/blockCard_node" + }, + { + "$ref": "#/definitions/layoutSection_node" + } + ] + } + } }, "required": ["version", "type", "content"], "additionalProperties": false diff --git a/src/__tests__/__snapshots__/helpers.js.snap b/src/__tests__/__snapshots__/helpers.js.snap deleted file mode 100644 index a8f2fcbc..00000000 --- a/src/__tests__/__snapshots__/helpers.js.snap +++ /dev/null @@ -1,205 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`filterRedundantErrors should handle anyOf 1`] = ` -Object { - "children": Object { - "a": Object { - "children": Object { - "b": Object { - "children": Object {}, - "errors": Array [ - Object { - "keyword": "required", - }, - ], - }, - }, - }, - }, -} -`; - -exports[`filterRedundantErrors should handle enum - sibling 1`] = ` -Object { - "children": Object { - "a2": Object { - "children": Object {}, - "errors": Array [ - Object { - "keyword": "additionalProperty", - }, - ], - }, - }, -} -`; - -exports[`filterRedundantErrors should handle enum 1`] = ` -Object { - "children": Object { - "a": Object { - "children": Object { - "b": Object { - "children": Object {}, - "errors": Array [ - Object { - "keyword": "enum", - }, - Object { - "keyword": "enum", - }, - ], - }, - }, - }, - }, -} -`; - -exports[`filterRedundantErrors should not remove anyOf errors if there are no children 1`] = ` -Object { - "children": Object { - "/object": Object { - "children": Object { - "/type": Object { - "children": Object {}, - "errors": Array [ - Object { - "keyword": "type", - }, - Object { - "keyword": "type", - }, - Object { - "keyword": "anyOf", - }, - ], - }, - }, - "errors": Array [], - }, - }, -} -`; - -exports[`filterRedundantErrors should prioritize required 1`] = ` -Object { - "children": Object { - "a": Object { - "children": Object {}, - "errors": Array [ - Object { - "keyword": "required", - }, - ], - }, - }, -} -`; - -exports[`makeTree works on array dataPath 1`] = ` -Object { - "children": Object { - "/root": Object { - "children": Object { - "/child/0": Object { - "children": Object {}, - "errors": Array [ - Object { - "dataPath": "/root/child/0", - }, - ], - }, - "/child/1": Object { - "children": Object {}, - "errors": Array [ - Object { - "dataPath": "/root/child/1", - }, - ], - }, - }, - "errors": Array [], - }, - }, -} -`; - -exports[`makeTree works on array item dataPath 1`] = ` -Object { - "children": Object { - "/root": Object { - "children": Object { - "/child/0": Object { - "children": Object { - "/grand-child": Object { - "children": Object {}, - "errors": Array [ - Object { - "dataPath": "/root/child/0/grand-child", - }, - ], - }, - }, - "errors": Array [], - }, - "/child/1": Object { - "children": Object { - "/grand-child": Object { - "children": Object {}, - "errors": Array [ - Object { - "dataPath": "/root/child/1/grand-child", - }, - ], - }, - }, - "errors": Array [], - }, - }, - "errors": Array [], - }, - }, -} -`; - -exports[`makeTree works on empty array 1`] = ` -Object { - "children": Object {}, -} -`; - -exports[`makeTree works on nested dataPath 1`] = ` -Object { - "children": Object { - "/root": Object { - "children": Object { - "/child": Object { - "children": Object {}, - "errors": Array [ - Object { - "dataPath": "/root/child", - }, - ], - }, - }, - "errors": Array [], - }, - }, -} -`; - -exports[`makeTree works on root dataPath 1`] = ` -Object { - "children": Object { - "": Object { - "children": Object {}, - "errors": Array [ - Object { - "dataPath": "", - }, - ], - }, - }, -} -`; diff --git a/src/__tests__/helpers.js b/src/__tests__/helpers.js index ed3d5709..b5d53c13 100644 --- a/src/__tests__/helpers.js +++ b/src/__tests__/helpers.js @@ -2,21 +2,82 @@ import { makeTree, filterRedundantErrors } from '../helpers'; describe('makeTree', () => { it('works on empty array', async () => { - expect(makeTree([])).toMatchSnapshot(); + expect(makeTree([])).toMatchInlineSnapshot(` + Object { + "children": Object {}, + } + `); }); it('works on root dataPath', async () => { - expect(makeTree([{ dataPath: '' }])).toMatchSnapshot(); + expect(makeTree([{ dataPath: '' }])).toMatchInlineSnapshot(` + Object { + "children": Object { + "": Object { + "children": Object {}, + "errors": Array [ + Object { + "dataPath": "", + }, + ], + }, + }, + } + `); }); it('works on nested dataPath', async () => { - expect(makeTree([{ dataPath: '/root/child' }])).toMatchSnapshot(); + expect(makeTree([{ dataPath: '/root/child' }])).toMatchInlineSnapshot(` + Object { + "children": Object { + "/root": Object { + "children": Object { + "/child": Object { + "children": Object {}, + "errors": Array [ + Object { + "dataPath": "/root/child", + }, + ], + }, + }, + "errors": Array [], + }, + }, + } + `); }); it('works on array dataPath', async () => { expect( makeTree([{ dataPath: '/root/child/0' }, { dataPath: '/root/child/1' }]) - ).toMatchSnapshot(); + ).toMatchInlineSnapshot(` + Object { + "children": Object { + "/root": Object { + "children": Object { + "/child/0": Object { + "children": Object {}, + "errors": Array [ + Object { + "dataPath": "/root/child/0", + }, + ], + }, + "/child/1": Object { + "children": Object {}, + "errors": Array [ + Object { + "dataPath": "/root/child/1", + }, + ], + }, + }, + "errors": Array [], + }, + }, + } + `); }); it('works on array item dataPath', async () => { @@ -25,7 +86,43 @@ describe('makeTree', () => { { dataPath: '/root/child/0/grand-child' }, { dataPath: '/root/child/1/grand-child' }, ]) - ).toMatchSnapshot(); + ).toMatchInlineSnapshot(` + Object { + "children": Object { + "/root": Object { + "children": Object { + "/child/0": Object { + "children": Object { + "/grand-child": Object { + "children": Object {}, + "errors": Array [ + Object { + "dataPath": "/root/child/0/grand-child", + }, + ], + }, + }, + "errors": Array [], + }, + "/child/1": Object { + "children": Object { + "/grand-child": Object { + "children": Object {}, + "errors": Array [ + Object { + "dataPath": "/root/child/1/grand-child", + }, + ], + }, + }, + "errors": Array [], + }, + }, + "errors": Array [], + }, + }, + } + `); }); }); @@ -59,7 +156,20 @@ describe('filterRedundantErrors', () => { }, }; filterRedundantErrors(tree); - expect(tree).toMatchSnapshot(); + expect(tree).toMatchInlineSnapshot(` + Object { + "children": Object { + "a": Object { + "children": Object {}, + "errors": Array [ + Object { + "keyword": "required", + }, + ], + }, + }, + } + `); }); it('should handle anyOf', async () => { @@ -88,7 +198,24 @@ describe('filterRedundantErrors', () => { }, }; filterRedundantErrors(tree); - expect(tree).toMatchSnapshot(); + expect(tree).toMatchInlineSnapshot(` + Object { + "children": Object { + "a": Object { + "children": Object { + "b": Object { + "children": Object {}, + "errors": Array [ + Object { + "keyword": "required", + }, + ], + }, + }, + }, + }, + } + `); }); it('should handle enum', async () => { @@ -120,7 +247,27 @@ describe('filterRedundantErrors', () => { }, }; filterRedundantErrors(tree); - expect(tree).toMatchSnapshot(); + expect(tree).toMatchInlineSnapshot(` + Object { + "children": Object { + "a": Object { + "children": Object { + "b": Object { + "children": Object {}, + "errors": Array [ + Object { + "keyword": "enum", + }, + Object { + "keyword": "enum", + }, + ], + }, + }, + }, + }, + } + `); }); it('should handle enum - sibling', async () => { @@ -148,7 +295,71 @@ describe('filterRedundantErrors', () => { }, }; filterRedundantErrors(tree); - expect(tree).toMatchSnapshot(); + expect(tree).toMatchInlineSnapshot(` + Object { + "children": Object { + "a2": Object { + "children": Object {}, + "errors": Array [ + Object { + "keyword": "additionalProperty", + }, + ], + }, + }, + } + `); + }); + + it('should handle enum - sibling with nested error', async () => { + const tree = { + children: { + a1: { + children: { + b1: { + children: {}, + errors: [ + { + keyword: 'additionalProperty', + }, + ], + }, + }, + errors: [], + }, + a2: { + children: {}, + errors: [ + { + keyword: 'enum', + }, + { + keyword: 'enum', + }, + ], + }, + }, + }; + filterRedundantErrors(tree); + expect(tree).toMatchInlineSnapshot(` + Object { + "children": Object { + "a1": Object { + "children": Object { + "b1": Object { + "children": Object {}, + "errors": Array [ + Object { + "keyword": "additionalProperty", + }, + ], + }, + }, + "errors": Array [], + }, + }, + } + `); }); it('should not remove anyOf errors if there are no children', async () => { @@ -177,6 +388,30 @@ describe('filterRedundantErrors', () => { }; filterRedundantErrors(tree); - expect(tree).toMatchSnapshot(); + expect(tree).toMatchInlineSnapshot(` + Object { + "children": Object { + "/object": Object { + "children": Object { + "/type": Object { + "children": Object {}, + "errors": Array [ + Object { + "keyword": "type", + }, + Object { + "keyword": "type", + }, + Object { + "keyword": "anyOf", + }, + ], + }, + }, + "errors": Array [], + }, + }, + } + `); }); }); diff --git a/src/helpers.js b/src/helpers.js index 0be47169..042fa9b8 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -70,7 +70,7 @@ export function filterRedundantErrors(root, parent, key) { * Need explicit `root.errors` check because `[].every(fn) === true` * https://en.wikipedia.org/wiki/Vacuous_truth#Vacuous_truths_in_mathematics */ - if (root.errors && getErrors(root).every(isEnumError)) { + if (root.errors && root.errors.length && getErrors(root).every(isEnumError)) { if ( getSiblings(parent)(root) // Remove any reference which becomes `undefined` later diff --git a/src/json/get-decorated-data-path.js b/src/json/get-decorated-data-path.js index 7fbc2e39..b5e3dcf2 100644 --- a/src/json/get-decorated-data-path.js +++ b/src/json/get-decorated-data-path.js @@ -1,15 +1,8 @@ +import { getPointers } from './utils'; + export default function getDecoratedDataPath(jsonAst, dataPath) { - // TODO: Better error handling - const pointers = dataPath.split('/').slice(1); - for (const index in pointers) { - pointers[index] = pointers[index] - .split('~1') - .join('/') - .split('~0') - .join('~'); - } let decoratedPath = ''; - pointers.reduce((obj, pointer) => { + getPointers(dataPath).reduce((obj, pointer) => { switch (obj.type) { case 'Object': { decoratedPath += `/${pointer}`; diff --git a/src/json/get-meta-from-path.js b/src/json/get-meta-from-path.js index e2580f7d..c03b307a 100644 --- a/src/json/get-meta-from-path.js +++ b/src/json/get-meta-from-path.js @@ -1,17 +1,11 @@ +import { getPointers } from './utils'; + export default function getMetaFromPath( jsonAst, dataPath, isIdentifierLocation ) { - // TODO: Better error handling - const pointers = dataPath.split('/').slice(1); - for (const index in pointers) { - pointers[index] = pointers[index] - .split('~1') - .join('/') - .split('~0') - .join('~'); - } + const pointers = getPointers(dataPath); const lastPointerIndex = pointers.length - 1; return pointers.reduce((obj, pointer, idx) => { switch (obj.type) { diff --git a/src/json/utils.js b/src/json/utils.js new file mode 100644 index 00000000..abf3f6b2 --- /dev/null +++ b/src/json/utils.js @@ -0,0 +1,12 @@ +// TODO: Better error handling +export const getPointers = dataPath => { + const pointers = dataPath.split('/').slice(1); + for (const index in pointers) { + pointers[index] = pointers[index] + .split('~1') + .join('/') + .split('~0') + .join('~'); + } + return pointers; +}; diff --git a/usage.js b/usage.js index 8eaa3d13..a9197646 100644 --- a/usage.js +++ b/usage.js @@ -3,7 +3,7 @@ const Ajv = require('ajv'); const schema = require('./src/__fixtures__/schema.json'); const data = require('./src/__fixtures__/data.json'); -const betterAjvErrors = require('./src'); +const betterAjvErrors = require('./lib/modern'); // options can be passed, e.g. {allErrors: true} // const ajv = new Ajv({ allErrors: true, async: 'es7', jsonPointers: true });