From 39a7132cc1b5c559164e44af4c92ea235615d42f Mon Sep 17 00:00:00 2001 From: Jeff Marquez Date: Wed, 24 Jan 2024 11:07:30 -0700 Subject: [PATCH] This commit signifies a MAJOR reorganization of this project. Spectral proper and Stoplight.io's integration of it currrently have significant functional gaps in regards to supported rules formats (.js vs .json vs .yml), abilities to split files, and use of remote (http) rulesets. Due to this as well as our need to leverage both Stoplight.io AND Spectral separately the ruleset has been re-created to meet the lowest common denominatior (Stoplight.io). Overview of the changes are: - Conversion and consolidation of rulesets into a single YAML file with spectral/stoplight default naming: .spectral.yml - Above change rendered existing test suites invalid and have been removed. Replacements tests to be considered in the future. - Current Testing now exists of linting a 'valid' OAS3.1 file against the ruleset. - Dev Dependencies have been updated. - npm test script has been updated to run spectral against the examples/valid folder Note-worthy Section Rules Added: - Document Structure: - Resource Objects - Attributes - Relationsihps - Related Resource Links - Resource Linkage - Resource Links - Compound Document - Fetching Data - Fetching Resources - Responses - Fetching Relationships - Inclusion of Related Resources - Sparse Fieldsets - Sorting - Pagination - Filtering - Creating/Updating/Deleting - Creating Resources - Updating Resources - Deleting Resources --- .editorconfig | 2 +- .eslintrc.yml | 309 -- .spectral.yml | 1143 ++++ README.md | 21 +- .../attributes/failing-rules.yaml | 1017 ---- .../resourceObjects/failing-rules.yaml | 1473 ----- .../resourceObjects/fields/failing-rules.yaml | 1233 ----- .../identification/failing-rules.yaml | 805 --- .../errors/errorObjects/failing-rules.yaml | 195 - .../errors/errorObjects/passing-rules.yaml | 188 - .../processingErrors/failing-rules.yaml | 1674 ------ .../fetchingResources/failing-rules.yaml | 1262 ----- cliTest/passing-rules.yaml | 1727 ------ .../invalid/invalid-example.yml | 362 +- examples/valid/valid-example.yml | 810 +++ package-lock.json | 2121 +++----- package.json | 23 +- rules/jsonapi-content-negotiation-clients.js | 26 - .../jsonapi-content-negotiation-ruleset.yaml | 9 - rules/jsonapi-content-negotiation-servers.js | 42 - ...onapi-document-structure-jsonapi-object.js | 70 - rules/jsonapi-document-structure-links.js | 63 - ...api-document-structure-meta-information.js | 24 - ...-document-structure-resource-attributes.js | 154 - ...ent-structure-resource-attributes.yaml.old | 30 - ...napi-document-structure-resource-fields.js | 33 - ...ument-structure-resource-identification.js | 156 - ...structure-resource-identification.yaml.old | 33 - ...nt-structure-resource-identifier-object.js | 338 -- ...ent-structure-resource-object-ruleset.yaml | 14 - ...ocument-structure-resource-object.yaml.old | 104 - ...api-document-structure-resource-objects.js | 315 -- rules/jsonapi-document-structure-ruleset.yaml | 18 - rules/jsonapi-document-structure-top-level.js | 66 - rules/jsonapi-errors-error-object.js | 341 -- rules/jsonapi-errors-error-object.yaml.old | 115 - rules/jsonapi-errors-processing-errors.js | 60 - rules/jsonapi-errors-ruleset.yaml | 9 - ...sonapi-fetching-data-fetching-resources.js | 82 - rules/jsonapi-fetching-data-ruleset.yaml | 8 - rules/jsonapi-query-parameters.js.old | 89 - rules/jsonapi-ruleset.yaml | 9 - test/.eslintrc.yml | 20 - test/assets/example-jsonapi-oas-resolved.json | 4836 ----------------- test/assets/jsonapi-schema.yaml | 287 - .../invalidApiDocumentArrayAttributesType.js | 818 --- .../invalidApiDocumentArrayNoForeignKeys.js | 839 --- .../invalidApiDocumentArrayNoLinksMember.js | 840 --- ...idApiDocumentArrayNoRelationshipsMember.js | 840 --- .../invalidApiDocumentSingleNoForeignKeys.js | 840 --- .../invalidApiDocumentSingleNoLinksMember.js | 840 --- ...dApiDocumentSingleNoRelationshipsMember.js | 840 --- .../invalidApiDocumentSingleType.js | 837 --- .../fields/invalidApiDocumentNoTypeOrId.js | 848 --- .../invalidApiDocumentArrayIdMember.js | 834 --- .../invalidApiDocumentArrayIdType.js | 834 --- .../invalidApiDocumentArrayTypeMember.js | 835 --- .../invalidApiDocumentArrayTypeType.js | 835 --- .../invalidApiDocumentSingleIdMember.js | 834 --- .../invalidApiDocumentSingleIdType.js | 834 --- .../invalidApiDocumentSingleTypeMember.js | 835 --- .../invalidApiDocumentSingleTypeType.js | 835 --- .../invalidApiDocumentArrayAttributesType.js | 671 --- .../invalidApiDocumentArrayIdRequired.js | 671 --- .../invalidApiDocumentArrayIdType.js | 671 --- .../invalidApiDocumentArrayStructure.js | 675 --- .../invalidApiDocumentArrayStructureLength.js | 680 --- .../invalidApiDocumentArrayTypeRequired.js | 671 --- .../invalidApiDocumentArrayTypeType.js | 671 --- .../invalidApiDocumentSingleAttributesType.js | 671 --- .../invalidApiDocumentSingleIdRequired.js | 672 --- .../invalidApiDocumentSingleIdType.js | 672 --- .../invalidApiDocumentSingleStructure.js | 659 --- ...invalidApiDocumentSingleStructureLength.js | 694 --- .../invalidApiDocumentSingleTypeRequired.js | 673 --- .../invalidApiDocumentSingleTypeType.js | 673 --- .../resourceObjects/invalidApiDocumentType.js | 674 --- .../invalidApiDocumentArrayStructure.js | 201 - .../invalidApiDocumentItemsCodeType.js | 192 - .../invalidApiDocumentItemsDetailType.js | 192 - .../invalidApiDocumentItemsIdType.js | 191 - .../invalidApiDocumentItemsLinksMembers.js | 197 - ...lidApiDocumentItemsLinksStructureLength.js | 197 - .../invalidApiDocumentItemsSourceMembers.js | 193 - ...alidApiDocumentItemsSourceParameterType.js | 192 - ...nvalidApiDocumentItemsSourcePointerType.js | 192 - ...idApiDocumentItemsSourceStructureLength.js | 196 - .../invalidApiDocumentItemsSourceType.js | 184 - .../invalidApiDocumentItemsStatusType.js | 192 - .../invalidApiDocumentItemsTitleType.js | 192 - .../invalidApiDocumentObjectStructure.js | 191 - ...invalidApiDocumentObjectStructureLength.js | 195 - ...dApiDocumentProcessingErrorsGeneralCode.js | 212 - .../errors/errorObjects/validApiDocument.js | 191 - .../invalidApiDocumentArrayMaxItems.js | 833 --- .../invalidApiDocumentArrayMaxItemsValue.js | 834 --- .../invalidApiDocumentArrayLevelSelfLink.js | 846 --- ...cumentArrayRelationshipLevelRelatedLink.js | 846 --- .../invalidApiDocumentSingleLevelSelfLink.js | 846 --- ...umentSingleRelationshipLevelRelatedLink.js | 846 --- .../invalidApiDocumentTopLevelLinks.js | 837 --- test/docs/utilsTests/mockApiDocument.js | 92 - test/docs/validApiDocument.js | 886 --- ...sonapi-content-negotiation-clients.test.js | 141 - ...sonapi-content-negotiation-servers.test.js | 428 -- ...-document-structure-jsonapi-object.test.js | 187 - test/jsonapi-document-structure-links.test.js | 812 --- ...ocument-structure-meta-information.test.js | 174 - ...ment-structure-resource-attributes.test.js | 883 --- ...-structure-resource-attributes.test.js.old | 445 -- ...document-structure-resource-fields.test.js | 159 - ...t-structure-resource-identification.js.old | 393 -- ...-structure-resource-identification.test.js | 912 ---- ...ructure-resource-identifier-object.test.js | 1076 ---- ...ocument-structure-resource-objects.test.js | 1566 ------ ...onapi-document-structure-top-level.test.js | 757 --- ...ument-stucture-resource-object.test.js.old | 1478 ----- test/jsonapi-errors-error-object.test.js.old | 1588 ------ test/jsonapi-errors-error-objects.test.js | 1485 ----- test/jsonapi-errors-processing-errors.test.js | 267 - ...i-fetching-data-fetching-resources.test.js | 551 -- test/jsonapi-query-parameters.test.js.old | 514 -- test/testsSetup.js | 12 - test/utils/.eslintrc.yml | 7 - test/utils/debugUtils.js | 95 - test/utils/disableAllRulesets.js | 31 - test/utils/displayRulesets.js | 38 - test/utils/enableSpecificRuleset.js | 37 - test/utils/formattedErrorMessage.js | 27 - test/utils/getAllRulesets.js | 34 - test/utils/getEnabledRules.js | 33 - test/utils/getRulesFromTestTitle.js | 72 - test/utils/handleSpectralResults.js | 74 - test/utils/processErrors.js | 59 - test/utils/refResolver.js | 134 - test/utils/setupSpectral.js | 28 - test/utils/setupSpectralBeforeEach.js | 51 - test/utilsTests/.eslintrc.yml | 2 - test/utilsTests/debugUtils.test.js | 132 - test/utilsTests/disableAllRulesets.test.js | 47 - test/utilsTests/displayRulesets.test.js | 90 - test/utilsTests/enableSpecificRuleset.test.js | 50 - test/utilsTests/formattedErrorMessage.test.js | 59 - test/utilsTests/getAllRulesets.test.js | 31 - test/utilsTests/getEnabledRules.test.js | 43 - test/utilsTests/getRulesFromTestTitle.test.js | 37 - test/utilsTests/handleSpectralResults.test.js | 91 - test/utilsTests/processErrors.test.js | 61 - test/utilsTests/refResolver.test.js | 316 -- test/utilsTests/setupSpectral.test.js | 59 - .../setupSpectralBeforeEach.test.js | 57 - 151 files changed, 2880 insertions(+), 68941 deletions(-) delete mode 100644 .eslintrc.yml create mode 100644 .spectral.yml delete mode 100644 cliTest/documentStructure/resourceObjects/attributes/failing-rules.yaml delete mode 100644 cliTest/documentStructure/resourceObjects/failing-rules.yaml delete mode 100644 cliTest/documentStructure/resourceObjects/fields/failing-rules.yaml delete mode 100644 cliTest/documentStructure/resourceObjects/identification/failing-rules.yaml delete mode 100644 cliTest/errors/errorObjects/failing-rules.yaml delete mode 100644 cliTest/errors/errorObjects/passing-rules.yaml delete mode 100644 cliTest/errors/processingErrors/failing-rules.yaml delete mode 100644 cliTest/fetchingData/fetchingResources/failing-rules.yaml delete mode 100644 cliTest/passing-rules.yaml rename test/assets/example-jsonapi-oas.yaml => examples/invalid/invalid-example.yml (64%) create mode 100644 examples/valid/valid-example.yml delete mode 100644 rules/jsonapi-content-negotiation-clients.js delete mode 100644 rules/jsonapi-content-negotiation-ruleset.yaml delete mode 100644 rules/jsonapi-content-negotiation-servers.js delete mode 100644 rules/jsonapi-document-structure-jsonapi-object.js delete mode 100644 rules/jsonapi-document-structure-links.js delete mode 100644 rules/jsonapi-document-structure-meta-information.js delete mode 100644 rules/jsonapi-document-structure-resource-attributes.js delete mode 100644 rules/jsonapi-document-structure-resource-attributes.yaml.old delete mode 100644 rules/jsonapi-document-structure-resource-fields.js delete mode 100644 rules/jsonapi-document-structure-resource-identification.js delete mode 100644 rules/jsonapi-document-structure-resource-identification.yaml.old delete mode 100644 rules/jsonapi-document-structure-resource-identifier-object.js delete mode 100644 rules/jsonapi-document-structure-resource-object-ruleset.yaml delete mode 100644 rules/jsonapi-document-structure-resource-object.yaml.old delete mode 100644 rules/jsonapi-document-structure-resource-objects.js delete mode 100644 rules/jsonapi-document-structure-ruleset.yaml delete mode 100644 rules/jsonapi-document-structure-top-level.js delete mode 100644 rules/jsonapi-errors-error-object.js delete mode 100644 rules/jsonapi-errors-error-object.yaml.old delete mode 100644 rules/jsonapi-errors-processing-errors.js delete mode 100644 rules/jsonapi-errors-ruleset.yaml delete mode 100644 rules/jsonapi-fetching-data-fetching-resources.js delete mode 100644 rules/jsonapi-fetching-data-ruleset.yaml delete mode 100644 rules/jsonapi-query-parameters.js.old delete mode 100644 rules/jsonapi-ruleset.yaml delete mode 100644 test/.eslintrc.yml delete mode 100644 test/assets/example-jsonapi-oas-resolved.json delete mode 100644 test/assets/jsonapi-schema.yaml delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayAttributesType.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoForeignKeys.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoLinksMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoRelationshipsMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoForeignKeys.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoLinksMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoRelationshipsMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleType.js delete mode 100644 test/docs/documentStructure/resourceObjects/fields/invalidApiDocumentNoTypeOrId.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdType.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeType.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdType.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeMember.js delete mode 100644 test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayAttributesType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdRequired.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructure.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructureLength.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeRequired.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleAttributesType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdRequired.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructure.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructureLength.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeRequired.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeType.js delete mode 100644 test/docs/documentStructure/resourceObjects/invalidApiDocumentType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentArrayStructure.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsCodeType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsDetailType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsIdType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsLinksMembers.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsLinksStructureLength.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsSourceMembers.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsSourceParameterType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsSourcePointerType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsSourceStructureLength.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsSourceType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsStatusType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentItemsTitleType.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentObjectStructure.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentObjectStructureLength.js delete mode 100644 test/docs/errors/errorObjects/invalidApiDocumentProcessingErrorsGeneralCode.js delete mode 100644 test/docs/errors/errorObjects/validApiDocument.js delete mode 100644 test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItems.js delete mode 100644 test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItemsValue.js delete mode 100644 test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayLevelSelfLink.js delete mode 100644 test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayRelationshipLevelRelatedLink.js delete mode 100644 test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleLevelSelfLink.js delete mode 100644 test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleRelationshipLevelRelatedLink.js delete mode 100644 test/docs/fetchingData/fetchingResources/invalidApiDocumentTopLevelLinks.js delete mode 100644 test/docs/utilsTests/mockApiDocument.js delete mode 100644 test/docs/validApiDocument.js delete mode 100644 test/jsonapi-content-negotiation-clients.test.js delete mode 100644 test/jsonapi-content-negotiation-servers.test.js delete mode 100644 test/jsonapi-document-structure-jsonapi-object.test.js delete mode 100644 test/jsonapi-document-structure-links.test.js delete mode 100644 test/jsonapi-document-structure-meta-information.test.js delete mode 100644 test/jsonapi-document-structure-resource-attributes.test.js delete mode 100644 test/jsonapi-document-structure-resource-attributes.test.js.old delete mode 100644 test/jsonapi-document-structure-resource-fields.test.js delete mode 100644 test/jsonapi-document-structure-resource-identification.js.old delete mode 100644 test/jsonapi-document-structure-resource-identification.test.js delete mode 100644 test/jsonapi-document-structure-resource-identifier-object.test.js delete mode 100644 test/jsonapi-document-structure-resource-objects.test.js delete mode 100644 test/jsonapi-document-structure-top-level.test.js delete mode 100644 test/jsonapi-document-stucture-resource-object.test.js.old delete mode 100644 test/jsonapi-errors-error-object.test.js.old delete mode 100644 test/jsonapi-errors-error-objects.test.js delete mode 100644 test/jsonapi-errors-processing-errors.test.js delete mode 100644 test/jsonapi-fetching-data-fetching-resources.test.js delete mode 100644 test/jsonapi-query-parameters.test.js.old delete mode 100644 test/testsSetup.js delete mode 100644 test/utils/.eslintrc.yml delete mode 100644 test/utils/debugUtils.js delete mode 100644 test/utils/disableAllRulesets.js delete mode 100644 test/utils/displayRulesets.js delete mode 100644 test/utils/enableSpecificRuleset.js delete mode 100644 test/utils/formattedErrorMessage.js delete mode 100644 test/utils/getAllRulesets.js delete mode 100644 test/utils/getEnabledRules.js delete mode 100644 test/utils/getRulesFromTestTitle.js delete mode 100644 test/utils/handleSpectralResults.js delete mode 100644 test/utils/processErrors.js delete mode 100644 test/utils/refResolver.js delete mode 100644 test/utils/setupSpectral.js delete mode 100644 test/utils/setupSpectralBeforeEach.js delete mode 100644 test/utilsTests/.eslintrc.yml delete mode 100644 test/utilsTests/debugUtils.test.js delete mode 100644 test/utilsTests/disableAllRulesets.test.js delete mode 100644 test/utilsTests/displayRulesets.test.js delete mode 100644 test/utilsTests/enableSpecificRuleset.test.js delete mode 100644 test/utilsTests/formattedErrorMessage.test.js delete mode 100644 test/utilsTests/getAllRulesets.test.js delete mode 100644 test/utilsTests/getEnabledRules.test.js delete mode 100644 test/utilsTests/getRulesFromTestTitle.test.js delete mode 100644 test/utilsTests/handleSpectralResults.test.js delete mode 100644 test/utilsTests/processErrors.test.js delete mode 100644 test/utilsTests/refResolver.test.js delete mode 100644 test/utilsTests/setupSpectral.test.js delete mode 100644 test/utilsTests/setupSpectralBeforeEach.test.js diff --git a/.editorconfig b/.editorconfig index 5acad87..4d24c8c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,4 +7,4 @@ end_of_line = lf insert_final_newline = true indent_style = space indent_size = 2 -quote_type = single +quote_type = double diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index daa04f5..0000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,309 +0,0 @@ -env: - mocha: true - node: true - es6: true -extends: "eslint:recommended" -parserOptions: - sourceType: "module" - ecmaVersion: 2021 - ecmaFeatures: - jsx: false -rules: - accessor-pairs: error - array-bracket-newline: - - error - - consistent - array-bracket-spacing: error - array-callback-return: error - array-element-newline: - - error - - consistent - arrow-body-style: - - error - - always - arrow-parens: - - error - - always - arrow-spacing: - - error - - after: true - before: true - block-scoped-var: error - block-spacing: error - brace-style: error - callback-return: error - camelcase: - - error - - properties: never - capitalized-comments: off - class-methods-use-this: error - comma-dangle: error - comma-spacing: - - error - - after: true - before: false - comma-style: - - error - - last - complexity: - - error - - max: 5 - computed-property-spacing: - - error - - never - consistent-return: - - warn - consistent-this: - - error - - self - curly: error - default-case: error - default-case-last: error - default-param-last: error - dot-location: - - error - - property - dot-notation: error - eol-last: error - eqeqeq: - - error - - always - - null: ignore - func-call-spacing: error - func-name-matching: error - func-names: error - func-style: - - error - - declaration - - allowArrowFunctions: true - function-paren-newline: error - generator-star-spacing: error - global-require: error - grouped-accessor-pairs: error - guard-for-in: error - handle-callback-err: error - id-blacklist: error - id-denylist: error - id-length: error - id-match: error - implicit-arrow-linebreak: - - error - - beside - indent: - - error - - 2 - indent-legacy: "off" - init-declarations: "off" - jsx-quotes: error - key-spacing: error - keyword-spacing: error - line-comment-position: error - linebreak-style: - - error - - unix - lines-around-comment: error - lines-around-directive: error - lines-between-class-members: error - max-classes-per-file: error - max-depth: error - max-len: "off" - max-lines: "off" - max-lines-per-function: "off" - max-nested-callbacks: - - error - - max: 5 - max-params: error - max-statements: error - max-statements-per-line: error - multiline-comment-style: off - multiline-ternary: error - new-parens: error - newline-after-var: off - newline-before-return: error - newline-per-chained-call: error - no-alert: error - no-array-constructor: error - no-await-in-loop: error - no-bitwise: error - no-buffer-constructor: error - no-caller: error - no-catch-shadow: error - no-cond-assign: - - error - - always - no-confusing-arrow: error - no-console: - - error - - allow: - - warn - - error - no-constructor-return: error - no-continue: error - no-div-regex: error - no-duplicate-imports: error - no-else-return: error - no-empty-function: error - no-eq-null: error - no-eval: error - no-extend-native: error - no-extra-bind: error - no-extra-label: error - no-extra-parens: error - no-floating-decimal: error - no-implicit-coercion: error - no-implicit-globals: error - no-implied-eval: error - no-inline-comments: error - no-invalid-this: error - no-iterator: error - no-label-var: error - no-labels: error - no-lone-blocks: error - no-lonely-if: error - no-loop-func: error - no-loss-of-precision: error - no-magic-numbers: "off" - no-mixed-operators: error - no-mixed-requires: error - no-multi-assign: error - no-multi-spaces: error - no-multi-str: error - no-multiple-empty-lines: error - no-native-reassign: error - no-negated-condition: error - no-negated-in-lhs: error - no-nested-ternary: error - no-new: error - no-new-func: error - no-new-object: error - no-new-require: error - no-new-wrappers: error - no-octal-escape: error - no-param-reassign: error - no-path-concat: error - no-plusplus: error - no-process-env: error - no-process-exit: error - no-promise-executor-return: error - no-proto: error - no-restricted-exports: error - no-restricted-globals: error - no-restricted-imports: error - no-restricted-modules: error - no-restricted-properties: error - no-restricted-syntax: error - no-return-assign: error - no-return-await: error - no-script-url: error - no-self-compare: error - no-sequences: error - no-shadow: error - no-spaced-func: error - no-sync: error - no-tabs: error - no-template-curly-in-string: error - no-ternary: "off" - no-throw-literal: error - no-trailing-spaces: "off" - no-undef-init: error - no-undefined: error - no-underscore-dangle: error - no-unmodified-loop-condition: error - no-unneeded-ternary: error - no-unreachable-loop: error - no-unused-expressions: error - no-use-before-define: error - no-useless-backreference: error - no-useless-call: error - no-useless-computed-key: error - no-useless-concat: error - no-useless-constructor: error - no-useless-rename: error - no-useless-return: error - no-var: error - no-void: error - no-warning-comments: error - no-whitespace-before-property: error - nonblock-statement-body-position: error - object-curly-newline: error - object-curly-spacing: - - error - - always - object-property-newline: error - object-shorthand: error - one-var: - - error - - never - one-var-declaration-per-line: error - operator-assignment: error - operator-linebreak: error - padded-blocks: - - error - - always - - allowSingleLineBlocks: true - padding-line-between-statements: error - prefer-arrow-callback: "off" - prefer-const: error - prefer-destructuring: error - prefer-exponentiation-operator: error - prefer-named-capture-group: error - prefer-numeric-literals: error - prefer-object-spread: error - prefer-promise-reject-errors: error - prefer-reflect: "off" - prefer-regex-literals: error - prefer-rest-params: error - prefer-spread: error - prefer-template: error - quote-props: "off" - quotes: - - error - - single - - avoidEscape: true - allowTemplateLiterals: true - radix: error - require-atomic-updates: error - require-await: error - require-jsdoc: error - require-unicode-regexp: error - rest-spread-spacing: error - semi: error - semi-spacing: error - semi-style: - - error - - last - sort-imports: off - sort-keys: "off" - sort-vars: error - space-before-blocks: - - error - - always - space-before-function-paren: - - error - - anonymous: always - named: never - asyncArrow: always - space-in-parens: - - error - - never - space-infix-ops: error - space-unary-ops: error - spaced-comment: - - error - - always - strict: - - error - - safe - switch-colon-spacing: error - symbol-description: error - template-curly-spacing: error - template-tag-spacing: error - unicode-bom: - - error - - never - valid-jsdoc: error - vars-on-top: error - wrap-iife: error - wrap-regex: error - yield-star-spacing: error - yoda: error diff --git a/.spectral.yml b/.spectral.yml new file mode 100644 index 0000000..a207302 --- /dev/null +++ b/.spectral.yml @@ -0,0 +1,1143 @@ +extends: + - spectral:oas +formats: + - oas3.1 + +aliases: + AllContentSchemas: + - "$.paths..content['application/vnd.api+json'].schema" + + ResourceObjects: + - "$.paths..responses..content[application/vnd.api+json].schema.properties.data.properties" + - "$.paths..responses..content[application/vnd.api+json].schema.properties.data.allOf[*].properties" + - "$.paths..responses..content[application/vnd.api+json].schema.properties.data.items.properties" + - "$.paths..responses..content[application/vnd.api+json].schema.properties.data.items.allOf[*].properties" + - "$.paths..content[application/vnd.api+json].schema.properties.included.items.properties" + - "$.paths..content[application/vnd.api+json].schema.properties.included.items.allOf[*].properties" + - "$.paths..patch.requestBody.content[application/vnd.api+json].schema.properties.data.properties" + - "$.paths..patch.requestBody.content[application/vnd.api+json].schema.properties.data.allOf[*].properties" + + POSTResourceObjects: + - "$.paths..post.requestBody.content[application/vnd.api+json].schema.properties.data.properties" + - "$.paths..post.requestBody.content[application/vnd.api+json].schema.properties.data.allOf[*].properties" + + LinkObjects: + - "#AllContentSchemas..properties[links]" + + MetaObjects: + - "#AllContentSchemas..properties[meta]" + + Relationships: + - "#AllContentSchemas..properties[relationships]" + + RelationshipData: + - "#Relationships..data" + + POSTRelationships: + - "$.paths..post.requestBody.content[application/vnd.api+json].schema.properties.data.properties[relationships].properties[*]" + - "$.paths..post.requestBody.content[application/vnd.api+json].schema.properties.data.allOf[*].properties[relationships].properties[*]" + + PATCHRelationships: + - "$.paths..patch.requestBody.content[application/vnd.api+json].schema.properties.data.properties[relationships].properties[*]" + - "$.paths..patch.requestBody.content[application/vnd.api+json].schema.properties.data.allOf[*].properties[relationships].properties[*]" + + SingleErrorResponses: + - "$.paths..responses[?(@property > '400' && @property < '500')].content[application/vnd.api+json].schema.properties.errors" + - "$.paths..responses[?(@property > '500' && @property < '600')].content[application/vnd.api+json].schema.properties.errors" + - "$.paths..responses[default].content[application/vnd.api+json].schema.properties.errors" + + ErrorObjects: + - "$.paths..responses[default,400,500].content[application/vnd.api+json].schema.properties.errors.items.properties" + - "$.paths..responses[default,400,500].content[application/vnd.api+json].schema.properties.errors.items.allOf[*].properties" + - "$.paths..responses[?(@property > '400' && @property < '500')].content[application/vnd.api+json].schema.properties.errors.items.properties" + - "$.paths..responses[?(@property > '400' && @property < '500')].content[application/vnd.api+json].schema.properties.errors.items.allOf[*].properties" + - "$.paths..responses[?(@property > '500' && @property < '600')].content[application/vnd.api+json].schema.properties.errors.items.properties" + - "$.paths..responses[?(@property > '500' && @property < '600')].content[application/vnd.api+json].schema.properties.errors.items.allOf[*].properties" + +rules: + +# --------------------------------------------------------------------------- +# Section 4 Content Negotiation +# --------------------------------------------------------------------------- + + content-type: + description: "Clients and Servers MUST send all JSON:API data in as Content-Type: application/vnd.api+json without any media type parameters." + documentationUrl: "https://jsonapi.org/format/1.0/#content-negotiation" + message: "content MUST be 'application/vnd.api+json'" + severity: error + given: + - "$.paths..requestBody.content" + - "$.paths..responses..content" + then: + field: "@key" + function: enumeration + functionOptions: + values: + - application/vnd.api+json + + 406-response-code: + description: "Servers MUST document and support response code 406 paths in case of invalid ACCEPT media values" + documentationUrl: "https://jsonapi.org/format/1.0/#content-negotiation-servers" + message: "All paths must support response codes: 406" + severity: error + given: "$.paths..responses" + then: + field: "406" + function: truthy + + 415-response-code: + description: "Servers MUST document and support response code 415 on POST or PATCH paths in case of invalid Content-Type media values" + documentationUrl: "https://jsonapi.org/format/1.0/#content-negotiation-servers" + message: "POST and PATCH paths must support response code: 415" + severity: error + given: "$.paths[*][post,patch].responses" + then: + field: "415" + function: truthy + +# --------------------------------------------------------------------------- +# Section 5 Document Structure +# Section 5.1 Top Level Object Schema +# --------------------------------------------------------------------------- + + top-level-json-object: + description: "A JSON object MUST be at the root of every JSON:API request/response body containing data" + documentationUrl: "https://jsonapi.org/format/1.0/#document-top-level" + message: "Request/response body must be wrapped in root level JSON object" + severity: error + given: "#AllContentSchemas" + then: + field: type + function: enumeration + functionOptions: + values: + - object + + top-level-json-properties: + description: "Root JSON object MUST follow the jsonapi schema" + documentationUrl: "https://jsonapi.org/format/1.0/#document-top-level" + message: "Root JSON object MUST follow the jsonapi schema" + severity: error + given: "#AllContentSchemas" + then: + field: "properties" + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + anyOf: + - required: ["data"] + - required: ["errors"] + - required: ["meta"] + not: + anyOf: + - required: ["data","errors"] + dependentRequired: + included: ["data"] + properties: + data: + type: object + properties: + type: + type: string + enum: + - object + - array + - "null" + errors: + type: object + properties: + type: + type: string + enum: + - array + meta: + type: object + properties: + type: + type: string + enum: + - object + jsonapi: + type: object + properties: + type: + type: string + enum: + - object + links: + type: object + properties: + type: + type: string + enum: + - object + included: + type: object + properties: + type: + type: string + enum: + - array + +# --------------------------------------------------------------------------- +# Section 5.2 Resource Objects +# --------------------------------------------------------------------------- + + resource-object-properties: + description: "Verify allowed properties in Resource Objects" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-objects" + message: "'data' objects/items MUST meet Resource Object restrictions" + severity: error + given: + - "#ResourceObjects" + - "#POSTResourceObjects" + then: + - field: type + function: truthy + - field: "@key" + function: enumeration + functionOptions: + values: + - id + - type + - attributes + - relationships + - links + - meta + +# TODO:// Error throws incorrectly (too much) in an allOf scenario where one item is valid, but the other does not. Changed to warn for now. + resource-object-id-required: + description: "Verify 'id' property in non-POST Resource Object" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-objects" + message: "Could be missing 'id' property. Please verify the resource." + severity: warn + given: "#ResourceObjects" + then: + field: id + function: truthy + +# --------------------------------------------------------------------------- +# Section 5.2.1 Resource Objects - Identification +# --------------------------------------------------------------------------- + + resource-object-property-types: + description: "'id' and 'type' MUST be of type 'string'" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-identification" + message: "'id' and 'type' MUST be of type 'string'" + severity: error + given: + - "#ResourceObjects.id" + - "#ResourceObjects.type" + - "#POSTResourceObjects.type" + then: + field: type + function: enumeration + functionOptions: + values: + - string + +# --------------------------------------------------------------------------- +# Section 5.2.2 Resource Objects - Fields +# --------------------------------------------------------------------------- + + resource-object-reserved-fields: + description: "'id' and 'type' MUST NOT exist in 'attributes' or 'relationships'" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-fields" + message: "'id' and 'type' MUST NOT exist in 'attributes' or 'relationships'" + severity: error + given: "#AllContentSchemas..properties[attributes,relationships].properties" + then: + - field: id + function: falsy + - field: type + function: falsy + +# --------------------------------------------------------------------------- +# Section 5.2.3 Resource Objects - Attributes +# --------------------------------------------------------------------------- + + attributes-object-type: + description: "The value of 'attributes' property MUST be an object" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-attributes" + message: "The value of 'attributes' property MUST be an object" + severity: error + given: "#AllContentSchemas..properties[attributes]" + then: + field: type + function: enumeration + functionOptions: + values: + - object + + attributes-object-properties: + description: "Attributes object MUST NOT contain a 'relationships' or 'links' property" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-attributes" + message: "Attributes object MUST NOT contain a 'relationships' or 'links' property" + severity: error + given: "#AllContentSchemas..properties[attributes]..properties" + then: + - field: relationships + function: falsy + - field: links + function: falsy + + attributes-object-foreign-keys: + description: "Foreign Keys SHOULD NOT appear in attributes. RECOMMEND using 'relationships'" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-attributes" + message: "Foreign key? If so, it would be better to remove and use a relationship." + severity: info + given: "#AllContentSchemas..properties[attributes]..properties[*]~" + then: + function: pattern + functionOptions: + notMatch: ".*_id$" + +# --------------------------------------------------------------------------- +# Section 5.2.4 Resource Objects - Relationships (Addresses 5.2.6 and 5.3) +# --------------------------------------------------------------------------- + + relationships-object-type: + description: "Relationships MUST be an object" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-relationships" + message: "Relationships MUST be an object" + severity: error + given: "#Relationships" + then: + field: type + function: enumeration + functionOptions: + values: + - object + + relationship-schema: + description: "relationship object MUST follow the schema" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-object-relationships" + message: "relationship object MUST follow the schema" + severity: error + given: "#Relationships.properties[*]" + then: + - field: type + function: enumeration + functionOptions: + values: + - object + - field: properties + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + anyOf: + - required: ["links"] + - required: ["data"] + - required: ["meta"] + properties: + links: + type: object + properties: + type: + type: string + enum: + - object + properties: + type: object + anyOf: + - required: ["self"] + - required: ["related"] + properties: + self: + type: object + related: + type: object + data: + type: object + properties: + type: + type: string + enum: + - object + - array + - "null" + meta: + type: object + properties: + type: + type: string + enum: + - object + additionalProperties: false + + relationship-data-properties: + description: "relationship data May only contain: 'id', 'type' and 'meta'" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-identifier-objects" + message: "relationship data May only contain: 'id', 'type' and 'meta'" + severity: error + given: + - "#RelationshipData.properties" + - "#RelationshipData.allOf[*].properties" + - "#RelationshipData.items.properties" + - "#RelationshipData.items.allOf[*].properties" + then: + field: "@key" + function: enumeration + functionOptions: + values: + - id + - type + - meta + + relationship-data-schema: + description: "relationship data items MUST follow schema" + documentationUrl: "https://jsonapi.org/format/1.0/#document-resource-identifier-objects" + message: "relationship data items MUST follow schema" + severity: error + given: + - "#RelationshipData.properties" + - "#RelationshipData.allOf[0].properties" + - "#RelationshipData.items.properties" + - "#RelationshipData.items.allOf[0].properties" + then: + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + required: ["id","type"] + properties: + id: + type: object + properties: + type: + type: string + enum: + - string + type: + type: object + properties: + type: + type: string + enum: + - string + meta: + type: object + properties: + type: + type: string + enum: + - object + +# --------------------------------------------------------------------------- +# Section 5.5 Resource Objects - Meta Information +# --------------------------------------------------------------------------- + + meta-object: + description: "'meta' property MUST be of type object" + documentationUrl: "https://jsonapi.org/format/1.0/#document-meta" + message: "'meta' property MUST be of type object" + severity: error + given: "#MetaObjects" + then: + field: type + function: enumeration + functionOptions: + values: + - object + +# --------------------------------------------------------------------------- +# Section 5.6 Resource Objects - Links +# --------------------------------------------------------------------------- + + links-object: + description: "'links' property MUST be an object" + documentationUrl: "https://jsonapi.org/format/1.0/#document-links" + message: "'links' property MUST be an object" + severity: error + given: "#LinkObjects" + then: + field: type + function: enumeration + functionOptions: + values: + - object + + links-object-schema: + description: "A link must be represented as either a string containing the link's URL or an object" + documentationUrl: "https://jsonapi.org/format/1.0/#document-links" + message: "'link' properties must be of type string or object" + severity: error + given: "#LinkObjects.properties[*]..[?(@property === 'type')]^" + then: + field: type + function: enumeration + functionOptions: + values: + - string + - object + + links-object-schema-properties: + description: "objects contained within a links object MUST contain 'href' (string) and MAY contain 'meta'" + documentationUrl: "https://jsonapi.org/format/1.0/#document-links" + message: "objects contained within a links object MUST contain 'href' (string) and MAY contain 'meta'" + severity: error + given: "#LinkObjects.properties..properties" + then: + - field: "@key" + function: enumeration + functionOptions: + values: + - href + - meta + - field: href + function: truthy + - field: href.type + function: enumeration + functionOptions: + values: + - string + +# --------------------------------------------------------------------------- +# Section 5.7 Resource Objects - JSON:API Object +# --------------------------------------------------------------------------- + + jsonapi-object: + description: "jsonapi object MUST match schema" + documentationUrl: "https://jsonapi.org/format/1.0/#document-jsonapi-object" + message: "jsonapi object MUST match schema" + severity: error + given: "#AllContentSchemas..properties[?(@property === 'jsonapi')]" + then: + - field: type + function: enumeration + functionOptions: + values: + - object + - field: "properties[*]~" + function: enumeration + functionOptions: + values: + - version + - field: properties.version + function: truthy + - field: properties.version.type + function: enumeration + functionOptions: + values: + - string + +# --------------------------------------------------------------------------- +# Section 6 Fetching Data +# Section 6.1 +# Section 6.2 Responses Codes - 200, 404 +# --------------------------------------------------------------------------- + + get-200-response-code: + description: "Servers MUST support response code 200 on GET paths on successful request" + documentationUrl: "https://jsonapi.org/format/1.0/#fetching-resources-responses" + message: "GET paths must support response code: 200" + severity: error + given: "$.paths[*][get].responses" + then: + field: "200" + function: truthy + +# TODO:// verify a 404 response exists on a GET request that returns a single resource + +# --------------------------------------------------------------------------- +# Section 6.3 Fetching Resources - Inclusion of Related Resources +# --------------------------------------------------------------------------- + + 400-response-code: + description: "Servers MUST support response code 400 for all paths" + message: "All paths must support response codes: 400" + severity: error + given: "$.paths..responses" + then: + field: "400" + function: truthy + + include-parameter: + description: "'include' query param MUST be a string array (csv)" + documentationUrl: "https://jsonapi.org/format/1.0/#fetching-includes" + message: "'include' query param MUST be a string array (csv)" + severity: error + given: "$.paths..parameters[?(@.name == 'include')]" + then: + - field: in + function: enumeration + functionOptions: + values: + - query + - field: style + function: truthy + - field: style + function: enumeration + functionOptions: + values: + - form + - field: explode + function: defined + - field: explode + function: falsy + - field: schema + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + properties: + type: + type: string + enum: + - array + items: + type: object + properties: + type: + type: string + enum: + - string + +# --------------------------------------------------------------------------- +# Section 6.4 Fetching Resources - Sparse Fieldsets +# --------------------------------------------------------------------------- + + fields-parameter: + description: "'fields' query param MUST be a deepObject" + documentationUrl: "https://jsonapi.org/format/1.0/#fetching-sparse-fieldsets" + message: "'fields' query param MUST be a deepObject" + severity: error + given: "$.paths..parameters[?(@.name == 'fields')]" + then: + - field: in + function: enumeration + functionOptions: + values: + - query + - field: style + function: truthy + - field: style + function: enumeration + functionOptions: + values: + - deepObject + - field: schema + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + properties: + type: + type: string + enum: + - object + +# --------------------------------------------------------------------------- +# Section 6.5 Fetching Resources - Sorting +# --------------------------------------------------------------------------- + + sort-parameter: + description: "'sort' query param MUST be a string array (csv)" + documentationUrl: "https://jsonapi.org/format/1.0/#fetching-sorting" + message: "'sort' query param MUST be a string array (csv)" + severity: error + given: "$.paths..parameters[?(@.name == 'sort')]" + then: + - field: in + function: enumeration + functionOptions: + values: + - query + - field: style + function: truthy + - field: style + function: enumeration + functionOptions: + values: + - form + - field: explode + function: defined + - field: explode + function: falsy + - field: schema + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + properties: + type: + type: string + enum: + - array + items: + type: object + properties: + type: + type: string + enum: + - string + +# --------------------------------------------------------------------------- +# Section 6.6 Fetching Resources - Pagination +# --------------------------------------------------------------------------- + +# TODO:// verify 'page' param only on collections + page-parameter: + description: "'page' query param MUST follow schema" + documentationUrl: "https://jsonapi.org/format/1.0/#fetching-pagination" + message: "'page' query param MUST follow schema" + severity: error + given: "$.paths..parameters[?(@.name == 'page')]" + then: + - field: in + function: enumeration + functionOptions: + values: + - query + - field: style + function: truthy + - field: style + function: enumeration + functionOptions: + values: + - deepObject + - field: schema + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + properties: + type: + type: string + enum: + - object + properties: + type: object + additionalProperties: false + properties: + cursor: + type: object + properties: + type: + type: string + enum: ["string"] + offset: + type: object + properties: + type: + type: string + enum: ["integer"] + format: + type: string + enum: ["int32"] + minimum: + type: integer + minimum: 0 + limit: + type: object + properties: + type: + type: string + enum: ["integer"] + format: + type: string + enum: ["int32"] + +# TODO:// verify first,last,prev,next links only on collections + +# --------------------------------------------------------------------------- +# Section 6.7 Fetching Resources - Filtering +# --------------------------------------------------------------------------- + +# TODO:// verify 'filter' param only on collections + +# --------------------------------------------------------------------------- +# Section 7.1 Creating Resources +# --------------------------------------------------------------------------- + +# TODO:// support x-http-method-override: PATCH + + post-requests-single-object: + description: "POST requests MAY only contain a single resource object" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating" + message: "POST requests MAY only contain a single resource object" + severity: error + given: "$.paths..post.requestBody.content[application/vnd.api+json].schema.properties.data[?(@property==='type' && @ === 'array')]" + then: + function: falsy + + post-relationships: + description: "If relationships exist in POST request, 'data' is REQUIRED" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating" + message: "If relationships exist in POST request, 'data' is REQUIRED" + severity: error + given: "#POSTRelationships" + then: + field: required + function: schema + functionOptions: + schema: + type: array + items: + type: string + anyOf: + - enum: + - data + - enum: + - data + - links + - meta + + 403-response-code: + description: "Servers MUST document and support response code 403" + message: "All paths must support response codes: 403" + severity: error + given: "$.paths..responses" + then: + field: "403" + function: truthy + + 201-response-location-header: + description: "A POST 201 response SHOULD return a Location header" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating-responses" + message: "A POST 201 response SHOULD return a Location header" + severity: info + given: "$.paths[*][post].responses.201.headers" + then: + field: Location + function: defined + + post-201-response: + description: "A POST 201 response MUST return the primary resource" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating-responses" + message: "A POST 201 response MUST return the primary resource" + severity: info + given: "$.paths[*][post].responses.201.content[application/vnd.api+json].schema" + then: + field: required + function: schema + functionOptions: + schema: + type: array + items: + type: string + anyOf: + - enum: + - data + - enum: + - data + - meta + - jsonapi + - links + + post-2xx-response-codes: + description: "POST requests MUST support one Of the following 2xx codes: 201, 202 or 204" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating-responses" + message: "POST requests MUST support one Of the following 2xx codes: 201, 202 or 204" + severity: error + given: "$.paths[*][post].responses" + then: + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + anyOf: + - required: ["201"] + - required: ["202"] + - required: ["204"] + + post-409-response-code: + description: "POST requests MUST document and support response code 409" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating-responses" + message: "POST paths must support response codes: 409" + severity: error + given: "$.paths[*][post].responses" + then: + field: "409" + function: truthy + + post-409-response: + description: "POST 409 response SHOULD return 'source' property to identify conflict" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating-responses" + message: "POST 409 response SHOULD return 'source' property to identify conflict" + severity: info + given: "$.paths[*][post].responses" + then: + field: "409" + function: falsy + +# --------------------------------------------------------------------------- +# Section 7.2 Updating Resources +# --------------------------------------------------------------------------- + +# TODO:// support x-http-method-override: PATCH + + put-disallowed: + description: "PUT verb is not allowed in jsonapi, use PATCH instead." + documentationUrl: "https://jsonapi.org/format/1.0/#crud-updating" + message: "PUT verb is not allowed in jsonapi, use PATCH instead." + severity: error + given: "$.paths[*][put]" + then: + - function: falsy + + patch-requests-single-object: + description: "PATCH requests MAY only contain a single resource object" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating" + message: "PATCH requests MAY only contain a single resource object" + severity: error + given: "$.paths..patch.requestBody.content[application/vnd.api+json].schema.properties.data[?(@property==='type' && @ === 'array')]" + then: + function: falsy + + patch-relationships: + description: "If relationships exist in PATCH request, 'data' is REQUIRED" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-creating" + message: "If relationships exist in PAST request, 'data' is REQUIRED" + severity: error + given: "#PATCHRelationships" + then: + field: required + function: schema + functionOptions: + schema: + type: array + items: + type: string + anyOf: + - enum: + - data + - enum: + - data + - links + - meta + + patch-2xx-response-codes: + description: "PATCH requests MUST support at least one of the following 2xx codes: 200, 202 or 204" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-updating-responses" + message: "POST requests MUST support at least one of the following 2xx codes: 200, 202 or 204" + severity: error + given: "$.paths[*][patch].responses" + then: + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + anyOf: + - required: ["200"] + - required: ["202"] + - required: ["204"] + + patch-404-response-code: + description: "PATCH requests MUST support response code 404" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-updating-responses" + message: "PATCH requests MUST support response code 404" + severity: error + given: "$.paths[*][patch].responses" + then: + field: "404" + function: truthy + + patch-409-response-code: + description: "PATCH requests MUST document and support response code 409" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-updating-responses" + message: "PATCH requests MUST support response codes: 409" + severity: error + given: "$.paths[*][patch].responses" + then: + field: "409" + function: truthy + + patch-409-response: + description: "PATCH 409 response SHOULD return 'source' property to identify conflict" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-updating-responses" + message: "PATCH 409 response SHOULD return 'source' property to identify conflict" + severity: info + given: "$.paths[*][patch].responses" + then: + field: "409" + function: falsy + +# --------------------------------------------------------------------------- +# Section 7.3 Updating Relationships +# --------------------------------------------------------------------------- + +# TODO:// Revisit if/when updating relationships becomes needed + +# --------------------------------------------------------------------------- +# Section 7.4 Deleting Resources +# --------------------------------------------------------------------------- + + delete-2xx-response-codes: + description: "DELETE requests MUST support at least one of the following 2xx codes: 200, 202 or 204" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-deleting-responses" + message: "DELETE requests MUST support at least one of the following 2xx codes: 200, 202 or 204" + severity: error + given: "$.paths[*][delete].responses" + then: + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + anyOf: + - required: ["200"] + - required: ["202"] + - required: ["204"] + + delete-404-response-code: + description: "DELETE requests MUST support response code 404" + documentationUrl: "https://jsonapi.org/format/1.0/#crud-deleting-responses" + message: "DELETE requests MUST support response code 404" + severity: error + given: "$.paths[*][delete].responses" + then: + field: "404" + function: truthy + +# --------------------------------------------------------------------------- +# Section 9 Errors +# Section 9.1 Errors - Processing Errors +# --------------------------------------------------------------------------- + + error-processing: + description: "When returning multiple errors choose the most generally available code '400' or '500'. Other error codes MUST return only a single error." + documentationUrl: "https://jsonapi.org/format/1.0/#errors-processing" + message: "Error Codes != 400 and != 500 MUST set maxItems to 1" + severity: error + given: "#SingleErrorResponses" + then: + - field: maxItems + function: truthy + - field: maxItems + function: enumeration + functionOptions: + values: + - 1 + +# --------------------------------------------------------------------------- +# Section 9.2 Errors - Error Object +# --------------------------------------------------------------------------- + + error-object-schema: + description: "Error objects MUST follow schema" + documentationUrl: "https://jsonapi.org/format/1.0/#error-objects" + message: "Error objects (item object) MUST follow schema" + severity: error + given: "#ErrorObjects" + then: + - field: "@key" + function: enumeration + functionOptions: + values: + - id + - links + - status + - code + - title + - detail + - source + - meta + - field: "links.type" + function: enumeration + functionOptions: + values: + - object + - field: "source.type" + function: enumeration + functionOptions: + values: + - object + - field: "meta.type" + function: enumeration + functionOptions: + values: + - object + - field: "status.type" + function: enumeration + functionOptions: + values: + - string + - field: "code.type" + function: enumeration + functionOptions: + values: + - string + - field: "title.type" + function: enumeration + functionOptions: + values: + - string + - field: "detail.type" + function: enumeration + functionOptions: + values: + - string + + error-object-links: + description: "Error object links property MUST contain 'about'" + documentationUrl: "https://jsonapi.org/format/1.0/#error-objects" + message: "Error object links property MUST contain 'about'" + severity: error + given: "#ErrorObjects.links.properties" + then: + - field: "about" + function: truthy + + error-object-source-schema: + description: "Error object source MUST follow schema" + documentationUrl: "https://jsonapi.org/format/1.0/#error-objects" + message: "Error object source MUST follow schema" + severity: error + given: "#ErrorObjects.source" + then: + field: "properties" + function: schema + functionOptions: + dialect: "draft2020-12" + schema: + type: object + properties: + parameter: + type: object + properties: + type: + type: string + enum: ["string"] + pointer: + type: object + properties: + "oneOf": + type: array + items: + oneOf: + - type: object + required: [type,format] + properties: + type: + type: string + enum: ["string"] + format: + type: string + enum: ["json-pointer"] + - type: object + properties: + type: + type: string + enum: ["array"] + items: + type: object + required: [type,format] + properties: + type: + type: string + enum: ["string"] + format: + type: string + enum: ["json-pointer"] diff --git a/README.md b/README.md index 8df5aad..85eab11 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,20 @@ For ways to integrate this ruleset into your Spectral linting suite. See [Sharing & Distributing Rulesets](https://meta.stoplight.io/docs/spectral/docs/guides/7-sharing-rulesets.md) at ## Organization -Rules and Rulesets are organized by section of the JSON:API specification: -- Primary Ruleset - - `./rules/jsonapi-ruleset.yaml` -- Main Sections - - `./rules/jsonapi-{name-of-section}-ruleset.yaml` -- Sub Sections - - `./rules/jsonapi-{name-of-section}.js` -Each file `extends` rules/rulesets contained in its corresponding subsections. +`.spectral.yml` - Spectral Ruleset + +The ruleset `extends` - `spectral:oas`, spectral's built-in OAS linting rules. + +The rules are generally organized by the JSON:API specification section the rule is mentioned in. Each rule notes the section url it realates to. + +`examples` folder contains valid and invalid OAS3.1 examples ## Contributing In lieu of a formal style guide (I know... ironic :grin:): -- Take care to maintain the existing coding style, including tests. -- Add tests for all new/edited rules including JSONPath testing. -- Verify all linting and tests PASS: `npm test` +- Take care to maintain the existing coding format. +- Make needed adjustments to valid example +- Verify all linting PASS: `npm test` ## License [MIT License](https://github.com/jmlue42/spectral-jsonapi-ruleset/blob/main/LICENSE) diff --git a/cliTest/documentStructure/resourceObjects/attributes/failing-rules.yaml b/cliTest/documentStructure/resourceObjects/attributes/failing-rules.yaml deleted file mode 100644 index 5aafbe4..0000000 --- a/cliTest/documentStructure/resourceObjects/attributes/failing-rules.yaml +++ /dev/null @@ -1,1017 +0,0 @@ -# This OpenAPI Document provides a way of testing rulesets using using Spectrals CLI Command. Covered ruleset include: -# - `jsonapi-document-structure-resource-sttributes.js` -# -# Usage (From Repo Root Location): -# spectral lint cliTest/documentStructure/resourceObjects/attributes/failing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-attributes.js --verbose -# -# This document will generate `8 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: OpenAPI Management Template - description: |- - This API manages information pertaining to users and articles - which is adhereing to JSON:API v1.0 standards. The goal of this template is - to provide a universal temaplte for testing all of the JSON:API v1.0 - specifications. This is to generate a failing scenario for the following section: - - DocumentStructure.ResourceObjects.Attributes - version: 1.2.1 -servers: - - url: https://api.template.com/v2 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - # Creating a foreign key to flag rule `document-structure-resource-array-attributes-no-foreign-keys` - noForeignKey_id: - type: string - # Creating a `relationships` member to flag rule `document-structure-resource-array-attributes-no-relationships-member` - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - # Creating a `links` member to flag rule `document-structure-resource-array-attributes-no-links-member` - links: - type: string - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - # Changing type to flag rule `document-structure-resource-single-attributes-type` - type: fail - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - # Creating a foreign key to flag rule `document-structure-resource-single-attributes-no-foreign-keys` - foreignKey_id: - type: string - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - # Creating a Relationships member to flag rule `document-structure-resource-single-attributes-no-relationships-member` - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - # Creating a Links member to flag rule `document-structure-resource-single-attributes-no-relationships-member` - links: - type: string - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - /articles: - get: - tags: - - articles - summary: List all articles - description: >- - Retrieve a list of articles with pagination and optional filters for - sorting and searching. - operationId: listArticles - security: [] - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria, e.g., `title,-author` for ascending by title and - descending by author. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - responses: - '200': - description: A list of articles - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the article - type: - type: string - description: Type of the resource (articles) - attributes: - # Changing `attributes` type to flag rule `document-structure-resource-array-attributes-type` - type: fail - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - articleListExample: - summary: Example response for article list - value: - data: - - type: articles - id: '301' - attributes: - title: Article Title - author: Author Name - content: Article content here. - post: - tags: - - articles - summary: Create a new article - description: Add a new article to the collection. - operationId: createArticle - security: [] - requestBody: - description: Payload to create a new article, containing article details. - required: true - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - examples: - articleCreateExample: - summary: Example request for creating an article - value: - data: - type: articles - attributes: - title: New Article Title - author: Author Name - content: Content of the new article. - responses: - '201': - description: New article created - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the article - type: - type: string - description: Type of the resource (articles) - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - articleCreatedExample: - summary: Example response for a created article - value: - data: - id: '302' - type: articles - attributes: - title: New Article Title - author: Author Name - content: Content of the new article. - /articles/{articleId}: - get: - tags: - - articles - summary: Get Article by ID - operationId: getArticleById - security: [] - parameters: - - name: articleId - in: path - required: true - description: Unique identifier of the article - schema: - type: string - responses: - '200': - description: Details of a specific article - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the article - type: - type: string - description: Type of the resource (articles) - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - article: - summary: Article Example - value: - data: - id: '301' - type: articles - attributes: - title: Article Title - author: Author Name - content: Article content here. - put: - tags: - - articles - summary: Update an article - operationId: updateArticle - security: [] - parameters: - - name: articleId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing article. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing article's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - responses: - '200': - description: Article successfully updated - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the article - type: - type: string - description: Type of the resource (articles) - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - delete: - tags: - - articles - summary: Delete an article - operationId: deleteArticle - security: [] - parameters: - - name: articleId - in: path - required: true - schema: - type: string - responses: - '204': - description: The article was successfully deleted. -components: - schemas: {} - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/cliTest/documentStructure/resourceObjects/failing-rules.yaml b/cliTest/documentStructure/resourceObjects/failing-rules.yaml deleted file mode 100644 index be0eabe..0000000 --- a/cliTest/documentStructure/resourceObjects/failing-rules.yaml +++ /dev/null @@ -1,1473 +0,0 @@ -# This OpenAPI Document provides a way of testing rulesets using using Spectrals CLI Command. Covered ruleset include: -# - `jsonapi-document-structure-resource-objects.js` -# -# Usage (From Repo Root Location): -# spectral lint cliTest/documentStructure/resourceObjects/failing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-objects.js -# -# This document will generate `15 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: User Management API - description: This API manages user information, conforming to JSON:API v1.0 standards. - version: 1.1.0 -servers: - - url: https://api.usermanagement.com/v1 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - # START - # Adding more members to creating failing scenarios even though this typically would not obtain these members - links: - type: object - meta: - type: object - # Adding seventh member to create two failing scenarios, one incorrect allowed member and reached max allowed members - fail: - type: string - # END - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - self: - type: string - format: uri - first: - type: string - format: uri - last: - type: string - format: uri - prev: - type: string - format: uri - next: - type: string - format: uri - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - # Changing `Resource Object` type to create a failing scenario, original 'object' - type: fail - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - # removing `id` member to create a failing scenario, since `id` member is required for HTTP PUT operations - # id: - # type: string - # description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: >- - Bad Request - Indicates that the server cannot process the request - due to a client error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-701 - status: '400' - title: Bad Request - detail: >- - The request could not be processed due to malformed - syntax. - links: - about: https://api.usermanagement.com/docs/errors/400 - '500': - description: Internal server error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-902 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/400 - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - # Creating failing scenario where an `id` member is required - # id: - # type: string - # description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - id: error-456 - status: '400' - title: Bad Request - detail: >- - The request could not be understood due to malformed - syntax. - links: - about: https://api.usermanagement.com/docs/errors/400 - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFound: - summary: Example of a not found error - value: - errors: - id: error-444 - status: '404' - title: Not Found - detail: The requested resource was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - # removing `type` member to create a failing scenario, since `type` member is required always - # type: - # type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - # Failing here, added a member that is not allowed in a single resource object as well as exceeding max length - fail: - type: string - links: - type: object - meta: - type: object - id: - # changing `id` member type from 'string' to 'object' to create a failing scenario - type: object - description: Unique identifier for the user - type: - # changing `type` member type from 'string' to 'object' to create a failing scenario - type: object - description: Type of the resource (users) - attributes: - # changing `attributes` member type from 'object' to 'fail' to create a failing scenario - type: fail - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '401': - description: Unauthorized - Authentication credentials were missing or invalid. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - unauthorizedError: - summary: Example of a 401 Unauthorized error - value: - errors: - - id: error-443 - status: '401' - title: Unauthorized - detail: >- - Authentication credentials were not provided or are - invalid. - links: - about: https://api.usermanagement.com/docs/errors/401 - '403': - description: >- - Forbidden - The request was valid, but the server is refusing action - due to insufficient permissions. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - forbiddenError: - summary: Example of a 403 Forbidden error - value: - errors: - - id: error-333 - status: '403' - title: Unauthorized - detail: You do not have permission to perform this aciton. - links: - about: https://api.usermanagement.com/docs/errors/403 - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - '401': - description: Unauthorized - Authentication credentials were missing or invalid. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - unauthorizedError: - summary: Example of a 401 Unauthorized error - value: - errors: - - id: error-223 - status: '401' - title: Unauthorized - detail: >- - Authentication credentials were not provided or are - invalid. - links: - about: https://api.usermanagement.com/docs/errors/401 - '403': - description: >- - Forbidden - The request was valid, but the server is refusing action - due to insufficient permissions. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - forbiddenError: - summary: Example of a 403 Forbidden error - value: - errors: - - id: error-543 - status: '403' - title: Unauthorized - detail: You do not have permission to perform this aciton. - links: - about: https://api.usermanagement.com/docs/errors/403 - '404': - description: The specified user was not found. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFoundError: - summary: Example of a 404 Not Found error - value: - errors: - - id: error-123 - status: '404' - title: Not Found - detail: The user with the specified ID was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - /books: - get: - tags: - - books - summary: List all books - description: Retrieve a list of books. - responses: - '200': - description: A list of books - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - # Creating a failing scenario for `id` member having incorrect type, original: 'string' - type: fail - description: Unique identifier for the book - type: - # Creating a failing scenario for `type` member having incorrect type, original: 'string' - type: fail - description: Type of the resource (books) - attributes: - # Creating a failing scenario for `attributes` member having incorrect type, original: 'object' - type: fail - required: - - title - - author - properties: - title: - type: string - description: Title of the book - author: - type: string - description: Author of the book - isbn: - type: string - description: ISBN number of the book - relationships: - type: object - properties: - publisher: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - self: - type: string - format: uri - first: - type: string - format: uri - last: - type: string - format: uri - prev: - type: string - format: uri - next: - type: string - format: uri - examples: - bookListExample: - summary: Example response for book list - value: - data: - - type: books - id: '101' - attributes: - title: "The Great Gatsby" - author: "F. Scott Fitzgerald" - isbn: "978-3-16-148410-0" - /events: - get: - tags: - - events - summary: List all events - description: Retrieve a list of events. - responses: - '200': - description: A list of events - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - # Creating failing scenario where `id` member is required - # id: - # type: string - # description: Unique identifier for the event - type: - type: string - description: Type of the resource (events) - attributes: - type: object - required: - - title - - startDate - properties: - title: - type: string - description: Title of the event - startDate: - type: string - format: date-time - description: Start date and time of the event - location: - type: string - description: Location of the event - relationships: - type: object - properties: - organizer: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - self: - type: string - format: uri - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of events available. - /articles: - get: - tags: - - articles - summary: List all articles - description: Retrieve a list of articles. - responses: - '200': - description: A list of articles - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the article - # Creating failing scenario where `type` member is required - # type: - # type: string - # description: Type of the resource (articles) - attributes: - type: object - required: - - title - - publishedDate - properties: - title: - type: string - description: Title of the article - publishedDate: - type: string - format: date - description: Date when the article was published - author: - type: string - description: Author of the article - relationships: - type: object - properties: - category: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - self: - type: string - format: uri - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of articles available. -components: - schemas: {} - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/cliTest/documentStructure/resourceObjects/fields/failing-rules.yaml b/cliTest/documentStructure/resourceObjects/fields/failing-rules.yaml deleted file mode 100644 index 05af847..0000000 --- a/cliTest/documentStructure/resourceObjects/fields/failing-rules.yaml +++ /dev/null @@ -1,1233 +0,0 @@ -# This OpenAPI Document provides a way of testing rulesets using using Spectrals CLI Command. Covered ruleset include: -# - `jsonapi-document-structure-resource-sttributes.js` -# -# Usage (From Repo Root Location): -# spectral lint cliTest/documentStructure/resourceObjects/fields/failing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-fields.js --verbose -# -# This document will generate `1 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: OpenAPI Management Template - description: |- - This API manages information pertaining to users and articles - which is adhereing to JSON:API v1.0 standards. The goal of this template is - to provide a universal temaplte for testing all of the JSON:API v1.0 - specifications. This is to generate a failing scenario for the following section: - - DocumentStructure.ResourceObjects.fields - version: 1.2.2 -servers: - - url: https://api.template.com/v1 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - # Inserting an `id` field to trigger rule `document-structure-resource-fields-no-type-or-id` - id: - type: string - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-102 - status: '400' - title: Bad Request - detail: The request is invalid. - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: >- - Bad Request - Indicates that the server cannot process the request - due to a client error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-701 - status: '400' - title: Bad Request - detail: >- - The request could not be processed due to malformed - syntax. - links: - about: https://api.usermanagement.com/docs/errors/400 - '500': - description: Internal server error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-902 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/400 - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFound: - summary: Example of a not found error - value: - errors: - id: error-444 - status: '404' - title: Not Found - detail: The requested resource was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequestExample: - summary: Example of a Bad Request response - value: - errors: - - status: 400 - title: Bad Request - detail: >- - The request payload is invalid. Please check the - request data. - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - '404': - description: The specified user was not found. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFoundError: - summary: Example of a 404 Not Found error - value: - errors: - - id: error-123 - status: '404' - title: Not Found - detail: The user with the specified ID was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. -components: - schemas: {} - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/cliTest/documentStructure/resourceObjects/identification/failing-rules.yaml b/cliTest/documentStructure/resourceObjects/identification/failing-rules.yaml deleted file mode 100644 index 7e203e6..0000000 --- a/cliTest/documentStructure/resourceObjects/identification/failing-rules.yaml +++ /dev/null @@ -1,805 +0,0 @@ -# This OpenAPI Document provides a way of testing rulesets using using Spectrals CLI Command. Covered ruleset include: -# - `jsonapi-document-structure-resource-identification.js` -# -# Usage (From Repo Root Location): -# spectral lint cliTest/documentStructure/resourceObjects/identification/failing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-identification.js --verbose -# -# This document will generate `8 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: OpenAPI Management Template - description: |- - This API manages information pertaining to users and articles - which is adhereing to JSON:API v1.0 standards. The goal of this template is - to provide a universal temaplte for testing all of the JSON:API v1.0 - specifications. This is to generate a failing scenario for the following section: - - DocumentStructure.ResourceObjects.identification - version: 1.2.2 -servers: - - url: https://api.template.com/v1 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - # Removing `id` member to trigger rule `document-structure-resource-array-identification-id-member` - # id: - # type: string - # description: Unique identifier for the user - # Removing `id` member to trigger rule `document-structure-resource-array-identification-type-member` - # type: - # type: string - # description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - # Removing `id` member to trigger the rule `document-structure-resource-single-identification-id-member` - # id: - # type: string - # description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - # Changing the type from 'string' to 'fail' to trigger rule `document-structure-resource-single-identification-id-type` - type: fail - description: Unique identifier for the user - # Removing `type` member to trigger rule `document-structure-resource-single-identification-type-member` - # type: - # type: string - # description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - # Changing the type from 'string' to 'fail' to trigger rule `document-structure-resource-single-identification-type-type` - type: fail - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - /articles: - get: - tags: - - articles - summary: List all articles - description: >- - Retrieve a list of articles with pagination and optional filters for - sorting and searching. - operationId: listArticles - security: [] - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria, e.g., `title,-author` for ascending by title and - descending by author. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - responses: - '200': - description: A list of articles - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - # Changing the type from 'string' to 'fail' to trigger rule `document-structure-resource-array-identification-id-type` - type: fail - description: Unique identifier for the article - type: - # Changing the type from 'string' to 'fail' to trigger rule `document-structure-resource-array-identification-type-type` - type: fail - description: Type of the resource (articles) - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - articleListExample: - summary: Example response for article list - value: - data: - - type: articles - id: '301' - attributes: - title: Article Title - author: Author Name - content: Article content here. - post: - tags: - - articles - summary: Create a new article - description: Add a new article to the collection. - operationId: createArticle - security: [] - requestBody: - description: Payload to create a new article, containing article details. - required: true - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - examples: - articleCreateExample: - summary: Example request for creating an article - value: - data: - type: articles - attributes: - title: New Article Title - author: Author Name - content: Content of the new article. - responses: - '201': - description: New article created - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the article - type: - type: string - description: Type of the resource (articles) - attributes: - type: object - required: - - title - - author - - content - properties: - title: - type: string - description: Title of the article - author: - type: string - description: Author of the article - content: - type: string - description: Content of the article - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - articleCreatedExample: - summary: Example response for a created article - value: - data: - id: '302' - type: articles - attributes: - title: New Article Title - author: Author Name - content: Content of the new article. -components: - schemas: {} - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/cliTest/errors/errorObjects/failing-rules.yaml b/cliTest/errors/errorObjects/failing-rules.yaml deleted file mode 100644 index 9b7c4f1..0000000 --- a/cliTest/errors/errorObjects/failing-rules.yaml +++ /dev/null @@ -1,195 +0,0 @@ -# This OpenAPI Document provides a way of testing all the rules for `jsonapi-errors-error-object.js` -# using Spectrals CLI Command -# -# Usage: -# spectral lint cliTest/errors/errorObjects/failing-rules.yaml --ruleset rules/jsonapi-errors-error-object.js --verbose -# -# This document will generate `22 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: User Information API - version: 1.0.0 - description: API for retrieving user information -paths: - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Successful response with user information - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - id: - type: string - type: - type: string - enum: - - user - attributes: - type: object - properties: - name: - type: string - email: - type: string - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: string - items: - type: object - properties: - idd: - type: string - id: - type: object - links: - type: string - properties: - about: - type: object - format: urie - aboutt: - type: string - format: uri - status: - type: object - code: - type: object - title: - type: object - detail: - type: object - source: - type: string - properties: - pointer: - type: object - parameter: - type: object - parameterr: - type: object - meta: - type: string - additionalProperties: true - required: - - detail - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - required: - - detail - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - required: - - detail -components: - schemas: - Test: - type: object - properties: - test: - type: string diff --git a/cliTest/errors/errorObjects/passing-rules.yaml b/cliTest/errors/errorObjects/passing-rules.yaml deleted file mode 100644 index 3397eb9..0000000 --- a/cliTest/errors/errorObjects/passing-rules.yaml +++ /dev/null @@ -1,188 +0,0 @@ -# This OpenAPI Document provides a way of testing all the rules for `jsonapi-errors-error-object.js` -# using Spectrals CLI Command -# -# Usage: -# spectral lint cliTest/errors/errorObjects/passing-rules.yaml --ruleset rules/jsonapi-errors-error-object.js --verbose -# -# This document will generate `0 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: User Information API - version: 1.0.0 - description: API for retrieving user information -paths: - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Successful response with user information - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - id: - type: string - type: - type: string - enum: - - user - attributes: - type: object - properties: - name: - type: string - email: - type: string - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - required: - - detail - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - required: - - detail - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - required: - - detail -components: - schemas: - Test: - type: object - properties: - test: - type: string diff --git a/cliTest/errors/processingErrors/failing-rules.yaml b/cliTest/errors/processingErrors/failing-rules.yaml deleted file mode 100644 index 17c6abb..0000000 --- a/cliTest/errors/processingErrors/failing-rules.yaml +++ /dev/null @@ -1,1674 +0,0 @@ -# This OpenAPI Document provides a way of testing all the rules for `jsonapi-errors-processing-errors.js` -# using Spectrals CLI Command -# -# Usage: -# spectral lint cliTest/errors/processingErrors/failing-rules.yaml --ruleset rules/jsonapi-errors-processing-errors.js --verbose -# -# This document will generate `2 errors` as expected for each rule. -openapi: 3.1.0 -info: - title: OpenAPI Management Template - description: |- - This API manages information pertaining to users and articles - which is adhereing to JSON:API v1.0 standards. The goal of this template is - to provide a universal temaplte for testing all of the JSON:API v1.0 - specifications. This is to generate a failing scenario for the following section: - - Errors.ProcessingErrors - version: 1.2.3 -servers: - - url: https://api.template.com/v1 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - # Removing `maxItems` keyword to trigger rule `errors-processing-errors-array-max-items` - # maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-102 - status: '400' - title: Bad Request - detail: The request is invalid. - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - # Increasing the `maxItems` greater than `1` to trigger rule `errors-processing-errors-array-max-items-value` - maxItems: 4 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: >- - Bad Request - Indicates that the server cannot process the request - due to a client error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-701 - status: '400' - title: Bad Request - detail: >- - The request could not be processed due to malformed - syntax. - links: - about: https://api.usermanagement.com/docs/errors/400 - '500': - description: Internal server error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-902 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/400 - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFound: - summary: Example of a not found error - value: - errors: - id: error-444 - status: '404' - title: Not Found - detail: The requested resource was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequestExample: - summary: Example of a Bad Request response - value: - errors: - - status: 400 - title: Bad Request - detail: >- - The request payload is invalid. Please check the - request data. - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - '404': - description: The specified user was not found. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFoundError: - summary: Example of a 404 Not Found error - value: - errors: - - id: error-123 - status: '404' - title: Not Found - detail: The user with the specified ID was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. -components: - schemas: - User: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: Email address of the user, must follow standard email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - UserResponse: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - UserListResponse: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: The link to the first page of data. Null if not available. - last: - type: string - format: uri - nullable: true - description: The link to the last page of data. Null if not available. - prev: - type: string - format: uri - nullable: true - description: The link to the previous page of data. Null if not available. - next: - type: string - format: uri - nullable: true - description: The link to the next page of data. Null if not available. - UserRequest: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - UserUpdateRequest: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - UserAttributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: Email address of the user, must follow standard email format. - role: - type: string - description: Role of the user in the system - RelationshipLinks: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - RelatedResource: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: Email address of the user, must follow standard email format. - role: - type: string - description: Role of the user in the system - Meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - PaginationLinks: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: The link to the first page of data. Null if not available. - last: - type: string - format: uri - nullable: true - description: The link to the last page of data. Null if not available. - prev: - type: string - format: uri - nullable: true - description: The link to the previous page of data. Null if not available. - next: - type: string - format: uri - nullable: true - description: The link to the next page of data. Null if not available. - JsonApiError: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as a string - value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - ErrorObject: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: HTTP status code applicable to this error, given as a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/cliTest/fetchingData/fetchingResources/failing-rules.yaml b/cliTest/fetchingData/fetchingResources/failing-rules.yaml deleted file mode 100644 index 14d8d15..0000000 --- a/cliTest/fetchingData/fetchingResources/failing-rules.yaml +++ /dev/null @@ -1,1262 +0,0 @@ -# This OpenAPI Document provides a way of testing rulesets using Spectrals CLI Command. Covered rulesets include: -# - `jsonapi-fetching-data-fetching-resources.js` -# -# Usage (From Repo Root Location): -# - spectral lint cliTest/fetchingData/fetchingResources/failing-rules.yaml --ruleset rules/jsonapi-fetching-data-fetching-resources.js --verbose -# -# This document will generate `5 errors` as expected for each ruleset ran -openapi: 3.1.0 -info: - title: OpenAPI Management Template - description: |- - This API manages information pertaining to users - which is adhereing to JSON:API v1.0 standards. The goal of this template is - to provide a universal temaplte for testing all of the JSON:API v1.0 - specifications. This is to generate a failing scenario for the following section: - - FetchingData.FetchingResources - version: 1.2.2 -servers: - - url: https://api.template.com/v1 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - # Removing `self` member to trigger rule `fetching-data-fetching-resources-array-level-self-link` - # self: - # type: string - # format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - # Removing `related` member to trigger rule `fetching-data-fetching-resources-array-relationship-level-related-link` - # related: - # type: string - # format: uri - links: - type: object - properties: - # Removing `self` member to trigger rule `fetching-data-fetching-resources-top-level-links` - # self: - # type: string - # format: uri - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-102 - status: '400' - title: Bad Request - detail: The request is invalid. - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - # Removing `self` member to trigger rule `fetching-data-fetching-resources-single-level-self-link` - # self: - # type: string - # format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - # Removing `related` member to trigger rule `fetching-data-fetching-resources-single-relationship-level-related-link` - # related: - # type: string - # format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: >- - Bad Request - Indicates that the server cannot process the request - due to a client error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-701 - status: '400' - title: Bad Request - detail: >- - The request could not be processed due to malformed - syntax. - links: - about: https://api.usermanagement.com/docs/errors/400 - '500': - description: Internal server error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-902 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/400 - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - self: - type: string - format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFound: - summary: Example of a not found error - value: - errors: - id: error-444 - status: '404' - title: Not Found - detail: The requested resource was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - self: - type: string - format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequestExample: - summary: Example of a Bad Request response - value: - errors: - - status: 400 - title: Bad Request - detail: >- - The request payload is invalid. Please check the - request data. - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - '404': - description: The specified user was not found. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFoundError: - summary: Example of a 404 Not Found error - value: - errors: - - id: error-123 - status: '404' - title: Not Found - detail: The user with the specified ID was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. -components: - schemas: {} - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/cliTest/passing-rules.yaml b/cliTest/passing-rules.yaml deleted file mode 100644 index a5a9ecd..0000000 --- a/cliTest/passing-rules.yaml +++ /dev/null @@ -1,1727 +0,0 @@ -# This OpenAPI Document provides a way of testing rulesets using Spectrals CLI Command. Covered rulesets include: -# - `jsonapi-errors-error-object.js` -# - `jsonapi-errors-processing-errors.js` -# - `jsonapi-document-structure-resource-objects.js` -# - `jsonapi-fetching-data-fetching-resources.js` -# - `jsonapi-document-structure-resource-attributes.js` -# - `jsonapi-document-structure-resource-identification.js` -# - `jsonapi-document-structure-resource-fields.js` -# -# Usage (From Repo Root Location): -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-errors-error-object.js --verbose -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-errors-processing-errors.js --verbose -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-objects.js --verbose -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-fetching-data-fetching-resources.js --verbose -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-attributes.js --verbose -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-identification.js --verbose -# - spectral lint cliTest/passing-rules.yaml --ruleset rules/jsonapi-document-structure-resource-fields.js --verbose -# -# This document will generate `0 errors` as expected for each ruleset ran -openapi: 3.1.0 -info: - title: OpenAPI Management Template - description: |- - This API manages information pertaining to users - which is adhereing to JSON:API v1.0 standards. The goal of this template is - to provide a universal template for testing all of the JSON:API v1.0 - specifications. This document adheres to the following sections: - - ContentNegotiation.ClientResponsibilities - - ContentNegotiation.ServerResponsibilities - - DocumentStructure - - DocumentStructure.TopLevel - - DocumentStructure.ResourceObjects - - DocumentStructure.ResourceObjects.Attributes - - DocumentStructure.ResourceObjects.Identification - - DocumentStructure.ResourceObjects.Fields - - DocumentStructure.Links - - DocumentStructure.MetaInformation - - DocumentStructure.MemberNames - - FetchingData.FetchingResources - - FetchingData.Sorting - - FetchingData.Pagination - - FetchingData.Filtering - - Errors.ProcessingErrors - - Errors.ErrorObjects - version: 1.2.3 -servers: - - url: https://api.template.com/v1 -x-jsonapi-object: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - additionalProperties: false -paths: - /users: - get: - tags: - - users - summary: List all users - description: >- - Retrieve a list of users with pagination and optional filters for - sorting and searching. - security: [] - responses: - '200': - description: A list of users - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - self: - type: string - format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - self: - type: string - format: uri - first: - type: string - format: uri - nullable: true - description: >- - The link to the first page of data. Null if not - available. - last: - type: string - format: uri - nullable: true - description: >- - The link to the last page of data. Null if not - available. - prev: - type: string - format: uri - nullable: true - description: >- - The link to the previous page of data. Null if not - available. - next: - type: string - format: uri - nullable: true - description: >- - The link to the next page of data. Null if not - available. - examples: - userListExample: - summary: Example response for user list - value: - data: - - type: users - id: '1' - attributes: - name: John Doe - email: john@example.com - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-102 - status: '400' - title: Bad Request - detail: The request is invalid. - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. - parameters: - - name: page[number] - in: query - schema: - type: integer - minimum: 1 - default: 1 - description: Page number for pagination - - name: page[size] - in: query - schema: - type: integer - minimum: 1 - default: 20 - description: Number of items per page - - name: filter - in: query - schema: - type: string - description: Filter string to narrow down the search - - name: sort - in: query - schema: - type: string - description: >- - Sorting criteria. E.g., `name,-email` for ascending by name and - descending by email. - - name: fields - in: query - schema: - type: string - description: Comma-separated list of fields to include in the response. - post: - tags: - - users - summary: Create a new user - requestBody: - description: Payload to create a new user, containing user details. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '201': - description: New user created - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - self: - type: string - format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: >- - Bad Request - Indicates that the server cannot process the request - due to a client error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-701 - status: '400' - title: Bad Request - detail: >- - The request could not be processed due to malformed - syntax. - links: - about: https://api.usermanagement.com/docs/errors/400 - '500': - description: Internal server error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-902 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/400 - /users/{userId}: - get: - tags: - - users - summary: Get User by ID - security: [] - description: Retrieves information for a specific user by their ID. - operationId: getUserById - parameters: - - name: userId - in: path - required: true - description: Unique identifier of the user - schema: - type: string - responses: - '200': - description: Details of a user - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - self: - type: string - format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - examples: - user: - summary: User Example - value: - data: - id: '12345' - type: user - attributes: - name: John Doe - email: john.doe@example.com - '404': - description: User Not Found - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFound: - summary: Example of a not found error - value: - errors: - id: error-444 - status: '404' - title: Not Found - detail: The requested resource was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - put: - tags: - - users - summary: Update a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - requestBody: - description: Payload to update an existing user. - required: true - content: - application/vnd.api+json: - schema: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - responses: - '200': - description: User updated - content: - application/vnd.api+json: - schema: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - links: - type: object - properties: - self: - type: string - format: uri - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard - email format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - '400': - description: Bad Request - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequestExample: - summary: Example of a Bad Request response - value: - errors: - - status: 400 - title: Bad Request - detail: >- - The request payload is invalid. Please check the - request data. - '500': - description: Internal Server Error - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - badRequest: - summary: Example of a bad request error - value: - errors: - - id: error-032 - status: '500' - title: Internal Server Error - detail: The server encountered an unexpected condition. - links: - about: https://api.usermanagement.com/docs/errors/500 - delete: - tags: - - users - summary: Delete a user - parameters: - - name: userId - in: path - required: true - schema: - type: string - responses: - '204': - description: The user was successfully deleted. - '404': - description: The specified user was not found. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - notFoundError: - summary: Example of a 404 Not Found error - value: - errors: - - id: error-123 - status: '404' - title: Not Found - detail: The user with the specified ID was not found. - links: - about: https://api.usermanagement.com/docs/errors/404 - '500': - description: Internal Server Error - Indicates a server-side error. - content: - application/vnd.api+json: - schema: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as - a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - examples: - internalServerErrorExample: - summary: Example of an internal server error response - value: - errors: - - id: error-500 - status: '500' - title: Internal Server Error - detail: >- - The server encountered an unexpected condition that - prevented it from fulfilling the request. -components: - schemas: - User: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: Email address of the user, must follow standard email format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - UserResponse: - type: object - description: Response schema for a single user or a newly created user. - properties: - data: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - included: - type: array - items: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - UserListResponse: - type: object - description: Response schema for a list of users with pagination details. - properties: - data: - type: array - items: - type: object - required: - - id - - type - properties: - id: - type: string - description: Unique identifier for the user - type: - type: string - description: Type of the resource (users) - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - relationships: - type: object - properties: - posts: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - links: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: The link to the first page of data. Null if not available. - last: - type: string - format: uri - nullable: true - description: The link to the last page of data. Null if not available. - prev: - type: string - format: uri - nullable: true - description: The link to the previous page of data. Null if not available. - next: - type: string - format: uri - nullable: true - description: The link to the next page of data. Null if not available. - UserRequest: - type: object - description: Request schema for creating a new user. - properties: - data: - type: object - required: - - type - - attributes - properties: - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - UserUpdateRequest: - type: object - description: Request schema for updating an existing user's details. - properties: - data: - type: object - required: - - id - - type - - attributes - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: >- - Email address of the user, must follow standard email - format. - role: - type: string - description: Role of the user in the system - UserAttributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: Email address of the user, must follow standard email format. - role: - type: string - description: Role of the user in the system - RelationshipLinks: - type: object - properties: - self: - type: string - format: uri - related: - type: string - format: uri - RelatedResource: - type: object - properties: - id: - type: string - type: - type: string - attributes: - type: object - required: - - name - - email - properties: - name: - type: string - description: Name of the user - email: - type: string - format: email - description: Email address of the user, must follow standard email format. - role: - type: string - description: Role of the user in the system - Meta: - type: object - properties: - totalCount: - type: integer - description: Total number of resources available. - lastUpdated: - type: string - format: date-time - description: The timestamp of the last update. - PaginationLinks: - type: object - properties: - first: - type: string - format: uri - nullable: true - description: The link to the first page of data. Null if not available. - last: - type: string - format: uri - nullable: true - description: The link to the last page of data. Null if not available. - prev: - type: string - format: uri - nullable: true - description: The link to the previous page of data. Null if not available. - next: - type: string - format: uri - nullable: true - description: The link to the next page of data. Null if not available. - JsonApiError: - type: object - required: - - errors - properties: - errors: - type: array - maxItems: 1 - items: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: >- - HTTP status code applicable to this error, given as a string - value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - ErrorObject: - type: object - properties: - id: - type: string - links: - type: object - properties: - about: - type: string - format: uri - status: - type: string - enum: - - '400' - - '401' - - '403' - - '404' - - '405' - - '406' - - '409' - - '422' - - '500' - - '502' - - '503' - description: HTTP status code applicable to this error, given as a string value. - code: - type: string - title: - type: string - detail: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - meta: - type: object - additionalProperties: true - securitySchemes: - BearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT Bearer token authentication - ApiKeyAuth: - type: apiKey - in: header - name: X-API-KEY - description: API Key based authentication -security: - - BearerAuth: [] - - ApiKeyAuth: [] diff --git a/test/assets/example-jsonapi-oas.yaml b/examples/invalid/invalid-example.yml similarity index 64% rename from test/assets/example-jsonapi-oas.yaml rename to examples/invalid/invalid-example.yml index be058fb..2c20f80 100644 --- a/test/assets/example-jsonapi-oas.yaml +++ b/examples/invalid/invalid-example.yml @@ -1,10 +1,10 @@ -openapi: 3.0.3 +openapi: 3.1.0 info: title: Sample JSON:API OAS File - description: Example file on how a JSON:API compliant API can be described in OAS v3+ + description: Example file on how a JSON:API v1 compliant API can be described in OAS v3.1 version: 1.0.0 contact: - name: Jeff Marquez + name: John Q. Public email: some_email@domain.com url: http://www.example.com tags: @@ -38,17 +38,20 @@ paths: - 'actions:read' parameters: - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/page' responses: '200': $ref: '#/components/responses/MyResource_Collection' + '400': + $ref: '#/components/responses/400Error' '401': $ref: '#/components/responses/401Error' '403': $ref: '#/components/responses/403Error' '406': - $ref: '#/components/responses/DefaultError' - '415': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/406Error' + '500': + $ref: '#/components/responses/500Error' 'default': $ref: '#/components/responses/DefaultError' post: @@ -65,14 +68,18 @@ paths: responses: '201': $ref: '#/components/responses/MyResource_Single' + '400': + $ref: '#/components/responses/400Error' '401': $ref: '#/components/responses/401Error' '403': $ref: '#/components/responses/403Error' '406': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/406Error' '415': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/415Error' + '500': + $ref: '#/components/responses/500Error' 'default': $ref: '#/components/responses/DefaultError' /myResources/{id}: @@ -87,18 +94,21 @@ paths: - 'actions:read' parameters: - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' - $ref: '#/components/parameters/fields' responses: '200': $ref: '#/components/responses/MyResource_Single' + '400': + $ref: '#/components/responses/400Error' '401': $ref: '#/components/responses/401Error' '403': $ref: '#/components/responses/403Error' '406': - $ref: '#/components/responses/DefaultError' - '415': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/406Error' + '500': + $ref: '#/components/responses/500Error' 'default': $ref: '#/components/responses/DefaultError' patch: @@ -117,14 +127,18 @@ paths: responses: '200': $ref: '#/components/responses/MyResource_Single' + '400': + $ref: '#/components/responses/400Error' '401': $ref: '#/components/responses/401Error' '403': $ref: '#/components/responses/403Error' '406': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/406Error' '415': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/415Error' + '500': + $ref: '#/components/responses/500Error' 'default': $ref: '#/components/responses/DefaultError' delete: @@ -141,17 +155,18 @@ paths: responses: '204': description: Successful Operation. No Content. + '400': + $ref: '#/components/responses/400Error' '401': $ref: '#/components/responses/401Error' '403': $ref: '#/components/responses/403Error' '406': - $ref: '#/components/responses/DefaultError' - '415': - $ref: '#/components/responses/DefaultError' + $ref: '#/components/responses/406Error' + '500': + $ref: '#/components/responses/500Error' 'default': - $ref: '#/components/responses/DefaultError' - + $ref: '#/components/responses/DefaultError' components: securitySchemes: ApiKeyAuth: @@ -175,12 +190,12 @@ components: description: Location of the resource in question schema: type: string - example: http://api.domain.com/v1/{resource-colleciton-name}/{id} + example: http://api.domain.com/v1/{resource-colleciton-name}/{id} WWWAuthenticate: description: Authentication Challenge Information schema: type: string - example: Bearer realm=domain.com + example: Bearer realm=domain.com parameters: id: name: id @@ -190,7 +205,43 @@ components: schema: type: string pattern: '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$' - example: 4257c52f-6c78-4747-8106-e185c081436b + example: 4257c52f-6c78-4747-8106-e185c081436b + include: + name: include + description: csv formatted parameter of relationship names to include in response + in: query + style: form + explode: false + schema: + type: array + items: + type: string + example: ["relationship","relationship.attribute"] + page: + name: page + description: Paging parameter. + in: query + schema: + type: object + required: ["cursor","limit"] + properties: + cursor: + type: string + limit: + type: integer + format: int32 + style: deepObject + sort: + name: sort + description: csv formatted parameter of fields to sort by + in: query + style: form + explode: false + schema: + type: array + items: + type: string + example: ["-age","name"] filter: name: filter description: schema for 'filter' query parameter @@ -253,9 +304,8 @@ components: type: object properties: self: - allOf: - - $ref: '#/components/schemas/Link' - - example: https://api.domain.com/v1/myResources/{id} + $ref: '#/components/schemas/Link' + example: https://api.domain.com/v1/myResources/{id} data: $ref: '#/components/schemas/MyResourceResponseObject' MyResource_Collection: @@ -268,17 +318,47 @@ components: - links - data properties: + jsonapi: + type: object + properties: + version: + type: string links: type: object properties: self: - allOf: - - $ref: '#/components/schemas/Link' - - example: https://api.domain.com/v1/myResources + $ref: '#/components/schemas/Link' + example: https://api.domain.com/v1/myResources data: type: array items: $ref: '#/components/schemas/MyResourceResponseObject' + 400Error: + description: 'Bad Request' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + $ref: '#/components/schemas/BaseErrorObject' + description: 'Bad Request' + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "400" + title: Bad Request + source: + parameter: "id" + - id: b6ad7d24-4dec-4ba0-931c-52731a9469e3 + status: "400" + title: Bad Request + source: + pointer: "/data/attributes/name" 401Error: description: 'Unauthorized: Invalid or Expired Authentication' headers: @@ -300,18 +380,17 @@ components: description: 'Unauthorized: Invalid or Expired Authentication' properties: status: - type: string enum: - "401" title: - type: string enum: - "Unauthorized" + maxItems: 1 example: errors: - - id: e50d3928-c1f0-4e10-888b-b110734656ab - status: "401" - title: Unauthorized + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "401" + title: Unauthorized 403Error: description: 'Forbidden: Request does not have necessary permissions' content: @@ -330,18 +409,128 @@ components: description: 'Forbidden: Request does not have necessary permissions' properties: status: - type: string enum: - "403" title: - type: string enum: - "Forbidden" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "403" + title: Forbidden + 406Error: + description: 'Not Acceptable' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Not Acceptable' + properties: + status: + enum: + - "406" + title: + enum: + - "Not Acceptable" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "406" + title: Not Acceptable + 409Error: + description: 'Conflict' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Conflict' + properties: + status: + enum: + - "409" + title: + enum: + - "Conflict" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "409" + title: Conflict + 415Error: + description: 'Unsupported Media Type' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Unsupported Media Type' + properties: + status: + enum: + - "415" + title: + enum: + - "Unsupported Media Type" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "415" + title: Unsupported Media Type + 500Error: + description: 'Internal Server Error' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + $ref: '#/components/schemas/BaseErrorObject' + description: 'Internal Server Error' example: errors: - id: e50d3928-c1f0-4e10-888b-b110734656ab - status: "403" - title: Forbidden + status: "400" + title: Bad Request + source: + parameter: "id" + - id: b6ad7d24-4dec-4ba0-931c-52731a9469e3 + status: "500" + title: Internal Server Error DefaultError: description: Error content: @@ -355,40 +544,7 @@ components: type: array items: $ref: '#/components/schemas/BaseErrorObject' - examples: - '400 - Bad Request': - value: - errors: - - id: e50d3928-c1f0-4e10-888b-b110734656ab - status: "400" - title: Bad Request - source: - parameter: "id" - '404 - Not Found': - value: - errors: - - id: e50d3928-c1f0-4e10-888b-b110734656ab - status: "404" - title: Not Found - '500 - Server Error': - value: - errors: - - id: e50d3928-c1f0-4e10-888b-b110734656ab - status: "500" - title: Internal Server Error - 'Multiple Errors': - value: - errors: - - id: e50d3928-c1f0-4e10-888b-b110734656ab - status: "400" - title: Bad Request - source: - parameter: "id" - - id: b6ad7d24-4dec-4ba0-931c-52731a9469e3 - status: "400" - title: Bad Request - source: - pointer: "/data/attributes/name" + maxItems: 1 schemas: MyResourceResponseObject: allOf: @@ -406,6 +562,8 @@ components: required: - name properties: + account_id: + type: string name: type: string example: do-hickey @@ -428,13 +586,11 @@ components: - related properties: self: - allOf: - - $ref: '#/components/schemas/Link' - - example: http://api.domain.com/v1/myResources/{id}/relationships/manufacturers + $ref: '#/components/schemas/Link' + example: http://api.domain.com/v1/myResources/{id}/relationships/manufacturers related: - allOf: - - $ref: '#/components/schemas/Link' - - example: http://api.domain.com/v1/manufacturers/{id} + type: string + example: http://api.domain.com/v1/manufacturers/{id} data: allOf: - $ref: '#/components/schemas/RelationshipDataObject' @@ -475,13 +631,19 @@ components: - data properties: data: - allOf: - - $ref: '#/components/schemas/RelationshipDataObject' - - type: object - properties: - type: - enum: - - manufacturers + type: object + required: + - id + - type + properties: + id: + type: string + pattern: '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$' + example: 2357c52f-6c78-4747-8106-e185c08143aa + type: + type: string + enum: + - manufacturers MyResourcePatchObject: allOf: - $ref: '#/components/schemas/IdentifierObject' @@ -501,9 +663,10 @@ components: type: string example: do-hickey description: - type: string + type: + - 'null' + - string example: thing that does stuff - nullable: true relationships: type: object required: @@ -522,9 +685,17 @@ components: type: enum: - manufacturers - nullable: true Link: - type: string + oneOf: + - type: string + - type: object + required: + - href + properties: + href: + type: string + meta: + type: object IdentifierObject: type: object required: @@ -537,6 +708,8 @@ components: example: 4257c52f-6c78-4747-8106-e185c081436b type: type: string + meta: + type: object RelationshipDataObject: type: object required: @@ -561,17 +734,7 @@ components: description: links that lead to further detail about the particular occurrence of the problem properties: about: - oneOf: - - type: string - - type: object - required: - - href - properties: - href: - type: string - meta: - type: object - additionalProperties: true + $ref: '#/components/schemas/Link' status: type: string description: the HTTP status code applicable to this problem @@ -592,12 +755,13 @@ components: description: a JSON Pointer [RFC6901] to the associated entity in the request document oneOf: - type: string + format: json-pointer - type: array items: type: string + format: json-pointer parameter: description: a string indicating which URI query parameter caused the error type: string meta: type: object - additionalProperties: true diff --git a/examples/valid/valid-example.yml b/examples/valid/valid-example.yml new file mode 100644 index 0000000..1765012 --- /dev/null +++ b/examples/valid/valid-example.yml @@ -0,0 +1,810 @@ +openapi: 3.1.0 +info: + title: Sample JSON:API OAS File + description: Example file on how a JSON:API v1 compliant API can be described in OAS v3.1 + version: 1.0.0 + contact: + name: John Q. Public + email: some_email@domain.com + url: http://www.example.com +tags: + - name: collection + description: tag description + - name: single + description: tag description +servers: + - url: https://api.domain.com/v1 + description: production + - url: https://api-sandbox.domain.com/v1 + description: production sandbox + - url: https://api.{environment}.domain.com/v1 + description: pre-production + variables: + environment: + enum: + - 'dev' + - 'qa' + default: 'dev' +paths: + /myResources: + get: + tags: + - collection + summary: Short Description + description: A longer MEANINGFUL description. Do not copy summary. + operationId: "getResourceList" + security: + - ApiKeyAuth: [] + AuthCode: + - 'actions:read' + parameters: + - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/sort' + responses: + '200': + $ref: '#/components/responses/MyResource_Collection' + '400': + $ref: '#/components/responses/400Error' + '401': + $ref: '#/components/responses/401Error' + '403': + $ref: '#/components/responses/403Error' + '406': + $ref: '#/components/responses/406Error' + '500': + $ref: '#/components/responses/500Error' + 'default': + $ref: '#/components/responses/DefaultError' + post: + tags: + - single + summary: Create Resource + description: A longer MEANINGFUL description. Do not copy summary. + operationId: "createResource" + security: + - ApiKeyAuth: [] + AuthCode: + - 'actions:write' + requestBody: + $ref: '#/components/requestBodies/MyResource_Post' + responses: + '201': + $ref: '#/components/responses/MyResource_Single' + '400': + $ref: '#/components/responses/400Error' + '401': + $ref: '#/components/responses/401Error' + '403': + $ref: '#/components/responses/403Error' + '406': + $ref: '#/components/responses/406Error' + '409': + $ref: '#/components/responses/409Error' + '415': + $ref: '#/components/responses/415Error' + '500': + $ref: '#/components/responses/500Error' + 'default': + $ref: '#/components/responses/DefaultError' + /myResources/{id}: + get: + tags: + - single + summary: Short Description + description: A longer MEANINGFUL description. Do not copy summary. + operationId: "getResourceById" + security: + - ApiKeyAuth: [] + AuthCode: + - 'actions:read' + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/fields' + responses: + '200': + $ref: '#/components/responses/MyResource_Single' + '400': + $ref: '#/components/responses/400Error' + '401': + $ref: '#/components/responses/401Error' + '403': + $ref: '#/components/responses/403Error' + '406': + $ref: '#/components/responses/406Error' + '500': + $ref: '#/components/responses/500Error' + 'default': + $ref: '#/components/responses/DefaultError' + patch: + tags: + - single + summary: Short Description + description: A longer MEANINGFUL description. Do not copy summary. + operationId: "updateResourceById" + security: + - ApiKeyAuth: [] + AuthCode: + - 'actions:write' + parameters: + - $ref: '#/components/parameters/id' + requestBody: + $ref: '#/components/requestBodies/MyResource_Patch' + responses: + '200': + $ref: '#/components/responses/MyResource_Single' + '400': + $ref: '#/components/responses/400Error' + '401': + $ref: '#/components/responses/401Error' + '404': + $ref: '#/components/responses/404Error' + '403': + $ref: '#/components/responses/403Error' + '406': + $ref: '#/components/responses/406Error' + '409': + $ref: '#/components/responses/409Error' + '415': + $ref: '#/components/responses/415Error' + '500': + $ref: '#/components/responses/500Error' + 'default': + $ref: '#/components/responses/DefaultError' + delete: + tags: + - single + summary: Short Description + description: A longer MEANINGFUL description. Do not copy summary. + operationId: "deleteResourceById" + security: + - ApiKeyAuth: [] + AuthCode: + - 'actions:delete' + parameters: + - $ref: '#/components/parameters/id' + responses: + '204': + description: Successful Operation. No Content. + '400': + $ref: '#/components/responses/400Error' + '401': + $ref: '#/components/responses/401Error' + '403': + $ref: '#/components/responses/403Error' + '404': + $ref: '#/components/responses/404Error' + '406': + $ref: '#/components/responses/406Error' + '500': + $ref: '#/components/responses/500Error' + 'default': + $ref: '#/components/responses/DefaultError' +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + description: Api Key value. First level of client identification and access control to proxy/gateway + in: header + name: api-key + AuthCode: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: 'https://api.domain.com/oauth/authorize' + tokenUrl: 'https://api.domain.com/oauth/token' + refreshUrl: 'https://api.domain.com/oauth/refresh' + scopes: + 'actions:write': modify actions the end-user has access to + 'actions:read': read actions the end-user has access to + 'actions:delete': delete actions the end-user has access to + headers: + Location: + description: Location of the resource in question + schema: + type: string + example: http://api.domain.com/v1/{resource-colleciton-name}/{id} + WWWAuthenticate: + description: Authentication Challenge Information + schema: + type: string + example: Bearer realm=domain.com + parameters: + id: + name: id + description: resource reference id + in: path + required: true + schema: + type: string + pattern: '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$' + example: 4257c52f-6c78-4747-8106-e185c081436b + include: + name: include + description: csv formatted parameter of relationship names to include in response + in: query + style: form + explode: false + schema: + type: array + items: + type: string + example: ["relationship","relationship.attribute"] + page: + name: page + description: Paging parameter. + in: query + schema: + type: object + required: ["cursor","limit"] + properties: + cursor: + type: string + limit: + type: integer + format: int32 + style: deepObject + sort: + name: sort + description: csv formatted parameter of fields to sort by + in: query + style: form + explode: false + schema: + type: array + items: + type: string + example: ["-age","name"] + filter: + name: filter + description: schema for 'filter' query parameter + in: query + schema: + type: object + style: deepObject + example: + attribute: "value" + attribute_2: "value1,value2" + relationship.attribute: "value" + fields: + name: fields + description: schema for 'fields' query parameter + in: query + schema: + type: object + style: deepObject + example: + resourceType: "fieldName" + resourceType2: "filedName1,fieldName2" + requestBodies: + MyResource_Patch: + required: true + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/MyResourcePatchObject' + MyResource_Post: + required: true + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/MyResourcePostObject' + responses: + MyResource_Single: + description: Successful Operation + headers: + Location: + $ref: '#/components/headers/Location' + content: + application/vnd.api+json: + schema: + type: object + required: + - links + - data + properties: + links: + type: object + properties: + self: + $ref: '#/components/schemas/Link' + example: https://api.domain.com/v1/myResources/{id} + data: + $ref: '#/components/schemas/MyResourceResponseObject' + MyResource_Collection: + description: Successful Operation + content: + application/vnd.api+json: + schema: + type: object + required: + - links + - data + properties: + jsonapi: + type: object + properties: + version: + type: string + links: + type: object + properties: + self: + $ref: '#/components/schemas/Link' + example: https://api.domain.com/v1/myResources + data: + type: array + items: + $ref: '#/components/schemas/MyResourceResponseObject' + 400Error: + description: 'Bad Request' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + $ref: '#/components/schemas/BaseErrorObject' + description: 'Bad Request' + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "400" + title: Bad Request + source: + parameter: "id" + - id: b6ad7d24-4dec-4ba0-931c-52731a9469e3 + status: "400" + title: Bad Request + source: + pointer: "/data/attributes/name" + 401Error: + description: 'Unauthorized: Invalid or Expired Authentication' + headers: + WWWAuthenticate: + $ref: '#/components/headers/WWWAuthenticate' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Unauthorized: Invalid or Expired Authentication' + properties: + status: + enum: + - "401" + title: + enum: + - "Unauthorized" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "401" + title: Unauthorized + 403Error: + description: 'Forbidden: Request does not have necessary permissions' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Forbidden: Request does not have necessary permissions' + properties: + status: + enum: + - "403" + title: + enum: + - "Forbidden" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "403" + title: Forbidden + 404Error: + description: 'Not Found' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Not Found' + properties: + status: + enum: + - "404" + title: + enum: + - "Not Found" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "404" + title: Not Found + 406Error: + description: 'Not Acceptable' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Not Acceptable' + properties: + status: + enum: + - "406" + title: + enum: + - "Not Acceptable" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "406" + title: Not Acceptable + 409Error: + description: 'Conflict' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Conflict' + properties: + status: + enum: + - "409" + title: + enum: + - "Conflict" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "409" + title: Conflict + 415Error: + description: 'Unsupported Media Type' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + allOf: + - $ref: '#/components/schemas/BaseErrorObject' + - type: object + description: 'Unsupported Media Type' + properties: + status: + enum: + - "415" + title: + enum: + - "Unsupported Media Type" + maxItems: 1 + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "415" + title: Unsupported Media Type + 500Error: + description: 'Internal Server Error' + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + $ref: '#/components/schemas/BaseErrorObject' + description: 'Internal Server Error' + example: + errors: + - id: e50d3928-c1f0-4e10-888b-b110734656ab + status: "400" + title: Bad Request + source: + parameter: "id" + - id: b6ad7d24-4dec-4ba0-931c-52731a9469e3 + status: "500" + title: Internal Server Error + DefaultError: + description: Error + content: + application/vnd.api+json: + schema: + type: object + required: + - errors + properties: + errors: + type: array + items: + $ref: '#/components/schemas/BaseErrorObject' + maxItems: 1 + schemas: + MyResourceResponseObject: + allOf: + - $ref: '#/components/schemas/IdentifierObject' + - type: object + required: + - attributes + - relationships + properties: + type: + enum: + - resources + attributes: + type: object + required: + - name + properties: + account_id: + type: string + name: + type: string + example: do-hickey + description: + type: string + example: thing that does stuff + relationships: + type: object + properties: + manufacturer: + type: object + required: + - links + - data + properties: + links: + type: object + required: + - self + - related + properties: + self: + $ref: '#/components/schemas/Link' + example: http://api.domain.com/v1/myResources/{id}/relationships/manufacturers + related: + type: string + example: http://api.domain.com/v1/manufacturers/{id} + data: + allOf: + - $ref: '#/components/schemas/RelationshipDataObject' + - type: object + properties: + type: + enum: + - manufacturers + MyResourcePostObject: + type: object + required: + - type + - attributes + properties: + type: + type: string + enum: + - resources + attributes: + type: object + required: + - name + properties: + name: + type: string + example: do-hickey + description: + type: string + example: thing that does stuff + relationships: + type: object + required: + - manufacturer + properties: + manufacturer: + type: object + required: + - data + properties: + data: + type: object + required: + - id + - type + properties: + id: + type: string + pattern: '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$' + example: 2357c52f-6c78-4747-8106-e185c08143aa + type: + type: string + enum: + - manufacturers + MyResourcePatchObject: + allOf: + - $ref: '#/components/schemas/IdentifierObject' + - type: object + required: + - attributes + properties: + type: + enum: + - resources + attributes: + type: object + required: + - name + properties: + name: + type: string + example: do-hickey + description: + type: + - 'null' + - string + example: thing that does stuff + relationships: + type: object + required: + - manufacturer + properties: + manufacturer: + type: object + required: + - data + properties: + data: + allOf: + - $ref: '#/components/schemas/RelationshipDataObject' + - type: object + properties: + type: + enum: + - manufacturers + Link: + oneOf: + - type: string + - type: object + required: + - href + properties: + href: + type: string + meta: + type: object + IdentifierObject: + type: object + required: + - id + - type + properties: + id: + type: string + pattern: '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$' + example: 4257c52f-6c78-4747-8106-e185c081436b + type: + type: string + meta: + type: object + RelationshipDataObject: + type: object + required: + - id + - type + properties: + id: + type: string + pattern: '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$' + example: 2357c52f-6c78-4747-8106-e185c08143aa + type: + type: string + BaseErrorObject: + type: object + description: JSON:API Error Object + properties: + id: + type: string + description: a unique identifier for this particular occurrence of the problem + links: + type: object + description: links that lead to further detail about the particular occurrence of the problem + properties: + about: + $ref: '#/components/schemas/Link' + status: + type: string + description: the HTTP status code applicable to this problem + code: + type: string + description: an application-specific error code + title: + type: string + description: a human-readable summary specific of the problem. Usually the http status friendly name. + detail: + type: string + description: a human-readable explanation specific to this occurrence of the problem + source: + type: object + description: an object containing references to the source of the error + properties: + pointer: + description: a JSON Pointer [RFC6901] to the associated entity in the request document + oneOf: + - type: string + format: json-pointer + - type: array + items: + type: string + format: json-pointer + parameter: + description: a string indicating which URI query parameter caused the error + type: string + meta: + type: object diff --git a/package-lock.json b/package-lock.json index f7d30ed..f26bfa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,147 +8,25 @@ "name": "spectral-jsonapi-ruleset", "version": "1.0.0", "license": "MIT", - "dependencies": { - "@stoplight/spectral-formats": "^1.4.0", - "@stoplight/spectral-functions": "^1.7.1" - }, "devDependencies": { - "@stoplight/spectral-core": "^1.14.2", - "@stoplight/spectral-parsers": "^1.0.2", - "chai": "^4.3.6", - "chai-as-promised": "^7.1.1", - "eslint": "^8.24.0", - "eslint-plugin-mocha": "^10.1.0", - "husky": "^8.0.1", - "jsonpath-plus": "^7.2.0", - "mocha": "^10.0.0", - "sinon": "^17.0.1" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", - "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/@eslint/js": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", - "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "@stoplight/spectral-cli": "^6.11.0", + "husky": "^8.0.3" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "node_modules/@asyncapi/specs": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-4.3.1.tgz", + "integrity": "sha512-EfexhJu/lwF8OdQDm28NKLJHFkx0Gb6O+rcezhZYLPIoNYKXJMh2J1vFGpwmfAcTTh+ffK44Oc2Hs1Q4sLBp+A==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "@types/json-schema": "^7.0.11" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true - }, "node_modules/@jsep-plugin/regex": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "dev": true, "engines": { "node": ">= 10.16.0" }, @@ -160,6 +38,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.3.tgz", "integrity": "sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==", + "dev": true, "engines": { "node": ">= 10.16.0" }, @@ -202,54 +81,55 @@ "node": ">= 8" } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "node_modules/@rollup/plugin-commonjs": { + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz", + "integrity": "sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0" } }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, "node_modules/@stoplight/better-ajv-errors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", + "dev": true, "dependencies": { "jsonpointer": "^5.0.0", "leven": "^3.1.0" @@ -265,6 +145,7 @@ "version": "3.21.0", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.0.tgz", "integrity": "sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==", + "dev": true, "dependencies": { "@stoplight/ordered-object-literal": "^1.0.3", "@stoplight/path": "^1.3.2", @@ -281,6 +162,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@stoplight/json-ref-readers/-/json-ref-readers-1.2.2.tgz", "integrity": "sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==", + "dev": true, "dependencies": { "node-fetch": "^2.6.0", "tslib": "^1.14.1" @@ -292,12 +174,14 @@ "node_modules/@stoplight/json-ref-readers/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/@stoplight/json-ref-resolver": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-3.1.6.tgz", "integrity": "sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==", + "dev": true, "dependencies": { "@stoplight/json": "^3.21.0", "@stoplight/path": "^1.3.2", @@ -315,9 +199,10 @@ } }, "node_modules/@stoplight/ordered-object-literal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.4.tgz", - "integrity": "sha512-OF8uib1jjDs5/cCU+iOVy+GJjU3X7vk/qJIkIJFqwmlJKrrtijFmqwbu8XToXrwTYLQTP+Hebws5gtZEmk9jag==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.5.tgz", + "integrity": "sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==", + "dev": true, "engines": { "node": ">=8" } @@ -326,14 +211,49 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz", "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==", + "dev": true, "engines": { "node": ">=8" } }, + "node_modules/@stoplight/spectral-cli": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.11.0.tgz", + "integrity": "sha512-IURDN47BPIf3q4ZyUPujGpBzuHWFE5yT34w9rTJ1GKA4SgdscEdQO9KoTjOPT4G4cvDlEV3bNxwQ3uRm7+wRlA==", + "dev": true, + "dependencies": { + "@stoplight/json": "~3.21.0", + "@stoplight/path": "1.3.2", + "@stoplight/spectral-core": "^1.18.3", + "@stoplight/spectral-formatters": "^1.3.0", + "@stoplight/spectral-parsers": "^1.0.3", + "@stoplight/spectral-ref-resolver": "^1.0.4", + "@stoplight/spectral-ruleset-bundler": "^1.5.2", + "@stoplight/spectral-ruleset-migrator": "^1.9.5", + "@stoplight/spectral-rulesets": ">=1", + "@stoplight/spectral-runtime": "^1.1.2", + "@stoplight/types": "^13.6.0", + "chalk": "4.1.2", + "fast-glob": "~3.2.12", + "hpagent": "~1.2.0", + "lodash": "~4.17.21", + "pony-cause": "^1.0.0", + "stacktracey": "^2.1.7", + "tslib": "^2.3.0", + "yargs": "17.3.1" + }, + "bin": { + "spectral": "dist/index.js" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/@stoplight/spectral-core": { "version": "1.18.3", "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.3.tgz", "integrity": "sha512-YY8x7X2SWJIhGTLPol+eFiQpWPz0D0mJdkK2i4A0QJG68KkNhypP6+JBC7/Kz3XWjqr0L/RqAd+N5cQLPOKZGQ==", + "dev": true, "dependencies": { "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "~3.21.0", @@ -361,18 +281,24 @@ "node": "^12.20 || >= 14.13" } }, - "node_modules/@stoplight/spectral-core/node_modules/jsonpath-plus": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.1.0.tgz", - "integrity": "sha512-gTaNRsPWO/K2KY6MrqaUFClF9kmuM6MFH5Dhg1VYDODgFbByw1yb7xu3hrViE/sz+dGOeMWgCzwUwQtAnCTE9g==", + "node_modules/@stoplight/spectral-core/node_modules/@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, "engines": { - "node": ">=12.0.0" + "node": "^12.20 || >=14.13" } }, "node_modules/@stoplight/spectral-formats": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.6.0.tgz", "integrity": "sha512-X27qhUfNluiduH0u/QwJqhOd8Wk5YKdxVmKM03Aijlx0AH1H5mYt3l9r7t2L4iyJrsBaFPnMGt7UYJDGxszbNA==", + "dev": true, "dependencies": { "@stoplight/json": "^3.17.0", "@stoplight/spectral-core": "^1.8.0", @@ -383,10 +309,33 @@ "node": ">=12" } }, + "node_modules/@stoplight/spectral-formatters": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-formatters/-/spectral-formatters-1.3.0.tgz", + "integrity": "sha512-ryuMwlzbPUuyn7ybSEbFYsljYmvTaTyD51wyCQs4ROzgfm3Yo5QDD0IsiJUzUpKK/Ml61ZX8ebgiPiRFEJtBpg==", + "dev": true, + "dependencies": { + "@stoplight/path": "^1.3.2", + "@stoplight/spectral-core": "^1.15.1", + "@stoplight/spectral-runtime": "^1.1.0", + "@stoplight/types": "^13.15.0", + "chalk": "4.1.2", + "cliui": "7.0.4", + "lodash": "^4.17.21", + "node-sarif-builder": "^2.0.3", + "strip-ansi": "6.0", + "text-table": "^0.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, "node_modules/@stoplight/spectral-functions": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.2.tgz", "integrity": "sha512-f+61/FtIkQeIo+a269CeaeqjpyRsgDyIk6DGr7iS4hyuk1PPk7Uf6MNRDs9FEIBh7CpdEJ+HSHbMLwgpymWTIw==", + "dev": true, "dependencies": { "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.1", @@ -408,6 +357,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.3.tgz", "integrity": "sha512-J0KW5Rh5cHWnJQ3yN+cr/ijNFVirPSR0pkQbdrNX30VboEl083UEDrQ3yov9kjLVIWEk9t9kKE7Eo3QT/k4JLA==", + "dev": true, "dependencies": { "@stoplight/json": "~3.21.0", "@stoplight/types": "^13.6.0", @@ -422,6 +372,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.4.tgz", "integrity": "sha512-5baQIYL0NJTSVy8v6RxOR4U51xOUYM8wJri1YvlAT6bPN8m0EIxMwfVYi0xUZEMVeHcWx869nIkoqyWmOutF2A==", + "dev": true, "dependencies": { "@stoplight/json-ref-readers": "1.2.2", "@stoplight/json-ref-resolver": "~3.1.6", @@ -433,10 +384,88 @@ "node": ">=12" } }, + "node_modules/@stoplight/spectral-ruleset-bundler": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.5.2.tgz", + "integrity": "sha512-4QUVUFAU+S7IQ9XeCu+0TQMYxKFpKnkOAfa9unRQ1iPL2cviaipEN6witpbAptdHJD3UUjx4OnwlX8WwmXSq9w==", + "dev": true, + "dependencies": { + "@rollup/plugin-commonjs": "~22.0.2", + "@stoplight/path": "1.3.2", + "@stoplight/spectral-core": ">=1", + "@stoplight/spectral-formats": ">=1", + "@stoplight/spectral-functions": ">=1", + "@stoplight/spectral-parsers": ">=1", + "@stoplight/spectral-ref-resolver": ">=1", + "@stoplight/spectral-ruleset-migrator": "^1.7.4", + "@stoplight/spectral-rulesets": ">=1", + "@stoplight/spectral-runtime": "^1.1.0", + "@stoplight/types": "^13.6.0", + "@types/node": "*", + "pony-cause": "1.1.1", + "rollup": "~2.79.0", + "tslib": "^2.3.1", + "validate-npm-package-name": "3.0.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/@stoplight/spectral-ruleset-migrator": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.9.5.tgz", + "integrity": "sha512-76n/HETr3UinVl/xLNldrH9p0JNoD8Gz4K75J6E4OHp4xD0P+BA2e8+W30HjIvqm1LJdLU2BNma0ioy+q3B9RA==", + "dev": true, + "dependencies": { + "@stoplight/json": "~3.21.0", + "@stoplight/ordered-object-literal": "~1.0.4", + "@stoplight/path": "1.3.2", + "@stoplight/spectral-functions": "^1.0.0", + "@stoplight/spectral-runtime": "^1.1.0", + "@stoplight/types": "^13.6.0", + "@stoplight/yaml": "~4.2.3", + "@types/node": "*", + "ajv": "^8.6.0", + "ast-types": "0.14.2", + "astring": "^1.7.5", + "reserved": "0.1.2", + "tslib": "^2.3.1", + "validate-npm-package-name": "3.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-rulesets": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.18.1.tgz", + "integrity": "sha512-buLzYi4rHjZOG2d5LC/s3YpySrCGrwR4irKDyrxLlbbqmB8BDOsrdO+7G9UGvRCJwAy/xs1VWcjokzGnG68K+Q==", + "dev": true, + "dependencies": { + "@asyncapi/specs": "^4.1.0", + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "^3.17.0", + "@stoplight/spectral-core": "^1.8.1", + "@stoplight/spectral-formats": "^1.5.0", + "@stoplight/spectral-functions": "^1.5.1", + "@stoplight/spectral-runtime": "^1.1.1", + "@stoplight/types": "^13.6.0", + "@types/json-schema": "^7.0.7", + "ajv": "^8.8.2", + "ajv-formats": "~2.1.0", + "json-schema-traverse": "^1.0.0", + "lodash": "~4.17.21", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@stoplight/spectral-runtime": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.2.tgz", "integrity": "sha512-fr5zRceXI+hrl82yAVoME+4GvJie8v3wmOe9tU+ZLRRNonizthy8qDi0Z/z4olE+vGreSDcuDOZ7JjRxFW5kTw==", + "dev": true, "dependencies": { "@stoplight/json": "^3.17.0", "@stoplight/path": "^1.3.2", @@ -454,6 +483,7 @@ "version": "12.5.0", "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", + "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" @@ -463,9 +493,10 @@ } }, "node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.20.0.tgz", + "integrity": "sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==", + "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" @@ -478,6 +509,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.3.tgz", "integrity": "sha512-Mx01wjRAR9C7yLMUyYFTfbUf5DimEpHMkRDQ1PKLe9dfNILbgdxyrncsOXM3vCpsQ1Hfj4bPiGl+u4u6e9Akqw==", + "dev": true, "dependencies": { "@stoplight/ordered-object-literal": "^1.0.1", "@stoplight/types": "^13.0.0", @@ -491,44 +523,56 @@ "node_modules/@stoplight/yaml-ast-parser": { "version": "0.0.48", "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.48.tgz", - "integrity": "sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==" + "integrity": "sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==", + "dev": true }, "node_modules/@types/es-aggregate-error": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.5.tgz", - "integrity": "sha512-N2YcF5clfLoFqpSXr50khdH9cItGytbDXti6UMc4948VivZp0g1tiJxes5yqtWO3LWQf/mArYrQFWarUWj8lcQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.6.tgz", + "integrity": "sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==", + "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/node": { - "version": "20.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.1.tgz", - "integrity": "sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==", + "version": "20.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", + "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/urijs": { - "version": "1.19.23", - "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.23.tgz", - "integrity": "sha512-3Zbk6RzmIpvKTNEHO2RcPOGHM++BQEITMqBRR1Ju32WbruhV/pygYgxiP3xA0b1B88zjzs0Izzjxsbj768+IjA==" + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "node_modules/@types/urijs": { + "version": "1.19.25", + "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.25.tgz", + "integrity": "sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==", "dev": true }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -536,31 +580,11 @@ "node": ">=6.5" } }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -576,6 +600,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, "peerDependencies": { "ajv": "^8.5.0" }, @@ -589,6 +614,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, "peerDependencies": { "ajv": "^8.0.1" } @@ -597,6 +623,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, "dependencies": { "ajv": "^8.0.0" }, @@ -609,15 +636,6 @@ } } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -642,29 +660,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "is-array-buffer": "^3.0.1" @@ -677,6 +677,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", @@ -693,19 +694,32 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "node_modules/as-table": { + "version": "1.0.55", + "resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz", + "integrity": "sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==", + "dev": true, + "dependencies": { + "printable-characters": "^1.0.42" + } + }, + "node_modules/ast-types": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", + "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, "engines": { - "node": "*" + "node": ">=4" } }, "node_modules/astring": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "dev": true, "bin": { "astring": "bin/astring" } @@ -714,6 +728,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -724,21 +739,14 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -756,16 +764,17 @@ "node": ">=8" } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", "dev": true }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -775,122 +784,20 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chai": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", - "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "dependencies": { - "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 5" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/cliui": { @@ -922,76 +829,29 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "node_modules/data-uri-to-buffer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", + "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==", "dev": true }, "node_modules/define-data-property": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -1005,6 +865,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -1021,29 +882,9 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" + "node": ">= 0.6.0" } }, "node_modules/emoji-regex": { @@ -1056,6 +897,7 @@ "version": "1.22.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -1108,6 +950,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.11.tgz", "integrity": "sha512-DCiZiNlMlbvofET/cE55My387NiLvuGToBEZDdK9U2G3svDCjL8WOgO5Il6lO83nQ8qmag/R9nArdpaFQ/m3lA==", + "dev": true, "dependencies": { "define-data-property": "^1.1.0", "define-properties": "^1.2.1", @@ -1129,6 +972,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.2", "has-tostringtag": "^1.0.0", @@ -1142,6 +986,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -1163,229 +1008,17 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", - "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.3", - "@eslint/js": "8.53.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz", - "integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^3.0.0", - "rambda": "^7.4.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, "engines": { "node": ">=6" } @@ -1393,46 +1026,40 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } }, "node_modules/fast-memoize": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", - "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==" + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", + "dev": true }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1445,57 +1072,27 @@ "node": ">=8" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" + "is-callable": "^1.1.3" } }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" + "node": ">=12" } }, "node_modules/fs.realpath": { @@ -1522,6 +1119,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1530,6 +1128,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -1547,6 +1146,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1560,19 +1160,11 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, "dependencies": { "function-bind": "^1.1.2", "has-proto": "^1.0.1", @@ -1583,10 +1175,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-source": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", + "integrity": "sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^2.0.0", + "source-map": "^0.6.1" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -1599,15 +1202,15 @@ } }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -1615,40 +1218,26 @@ "node": "*" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, "node_modules/globalthis": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -1663,6 +1252,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -1670,16 +1260,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1697,6 +1288,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.2" }, @@ -1708,6 +1300,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1719,6 +1312,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1730,6 +1324,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -1744,6 +1339,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -1751,13 +1347,13 @@ "node": ">= 0.4" } }, - "node_modules/he": { + "node_modules/hpagent": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", "dev": true, - "bin": { - "he": "bin/he" + "engines": { + "node": ">=14" } }, "node_modules/husky": { @@ -1775,49 +1371,16 @@ "url": "https://github.com/sponsors/typicode" } }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/immer": { "version": "9.0.21", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1838,6 +1401,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.2", "hasown": "^2.0.0", @@ -1851,6 +1415,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -1864,6 +1429,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -1871,22 +1437,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -1902,6 +1457,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1909,10 +1465,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -1957,6 +1526,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1977,6 +1547,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -1987,28 +1558,20 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/estree": "*" } }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -2024,6 +1587,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -2035,6 +1599,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -2049,6 +1614,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -2063,6 +1629,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, "dependencies": { "which-typed-array": "^1.1.11" }, @@ -2073,22 +1640,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -2099,60 +1655,46 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/jsep": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==", + "dev": true, "engines": { "node": ">= 10.16.0" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "node_modules/jsonc-parser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" + "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, "node_modules/jsonpath-plus": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", - "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.1.0.tgz", + "integrity": "sha512-gTaNRsPWO/K2KY6MrqaUFClF9kmuM6MFH5Dhg1VYDODgFbByw1yb7xu3hrViE/sz+dGOeMWgCzwUwQtAnCTE9g==", "dev": true, "engines": { "node": ">=12.0.0" @@ -2162,229 +1704,80 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.topath": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", - "integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==" + "integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==", + "dev": true }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dev": true, "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "sourcemap-codec": "^1.4.8" } }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" + "node": ">= 8" } }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=10" + "node": ">=8.6" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "*" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, "node_modules/nimma": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.2.tgz", "integrity": "sha512-V52MLl7BU+tH2Np9tDrIXK8bql3MVUadnMIl/0/oZSGC9keuro0O9UUv9QKp0aMvtN8HRew4G7byY7H4eWsxaQ==", + "dev": true, "dependencies": { "@jsep-plugin/regex": "^1.0.1", "@jsep-plugin/ternary": "^1.0.2", @@ -2403,55 +1796,17 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-6.0.1.tgz", "integrity": "sha512-EvGovdvau6FyLexFH2OeXfIITlgIbgZoAZe3usiySeaIDm5QS+A10DKNpaPBBqqRSZr2HN6HVNXxtwUAr2apEw==", + "dev": true, "optional": true, "engines": { "node": ">=10.0.0" } }, - "node_modules/nise": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", - "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -2467,19 +1822,24 @@ } } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/node-sarif-builder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-2.0.3.tgz", + "integrity": "sha512-Pzr3rol8fvhG/oJjIq2NTVB0vmdNNlz22FENhhPojYRZ4/ee08CfK4YuKmuL54V9MLhI1kpzxfOJ/63LzmZzDg==", "dev": true, + "dependencies": { + "@types/sarif": "^2.1.4", + "fs-extra": "^10.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14" } }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2488,102 +1848,36 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" + "wrappy": "1" } }, "node_modules/path-is-absolute": { @@ -2595,39 +1889,12 @@ "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2644,23 +1911,22 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-1.1.1.tgz", "integrity": "sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==", + "dev": true, "engines": { "node": ">=12.0.0" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } + "node_modules/printable-characters": { + "version": "1.0.42", + "resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz", + "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", + "dev": true }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -2685,37 +1951,11 @@ } ] }, - "node_modules/rambda": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz", - "integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==", - "dev": true - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -2741,17 +1981,35 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/reserved": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved/-/reserved-0.1.2.tgz", + "integrity": "sha512-/qO54MWj5L8WCBP9/UNe2iefJc+L9yETbH32xO/ft/EYPOTCR5k+azvDUgdCOKwZH8hXwPd0b8XBL78Nn2U69g==", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.8" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/reusify": { @@ -2764,19 +2022,19 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, "bin": { - "rimraf": "bin.js" + "rollup": "dist/bin/rollup" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { @@ -2803,12 +2061,13 @@ } }, "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -2819,35 +2078,19 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", + "integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2855,26 +2098,20 @@ "node_modules/safe-stable-stringify": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==", + "dev": true }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dev": true, "dependencies": { "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2884,6 +2121,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, "dependencies": { "define-data-property": "^1.0.1", "functions-have-names": "^1.2.3", @@ -2893,31 +2131,11 @@ "node": ">= 0.4" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -2931,6 +2149,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-eval/-/simple-eval-1.0.0.tgz", "integrity": "sha512-kpKJR+bqTscgC0xuAl2xHN6bB12lHjC2DCUfqjAx19bQyO3R2EVLOurm3H9AUltv/uFVcSCVNc6faegR+8NYLw==", + "dev": true, "dependencies": { "jsep": "^1.1.2" }, @@ -2938,31 +2157,30 @@ "node": ">=12" } }, - "node_modules/sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, + "node_modules/stacktracey": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/stacktracey/-/stacktracey-2.1.8.tgz", + "integrity": "sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==", "dev": true, - "engines": { - "node": ">=0.3.1" + "dependencies": { + "as-table": "^1.0.36", + "get-source": "^2.0.12" } }, "node_modules/string-width": { @@ -2983,6 +2201,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -2999,6 +2218,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3012,6 +2232,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3033,18 +2254,6 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3057,6 +2266,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -3078,50 +2299,20 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true }, "node_modules/typed-array-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -3135,6 +2326,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -3152,6 +2344,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -3170,6 +2363,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -3183,6 +2377,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -3196,12 +2391,23 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -3209,49 +2415,48 @@ "node_modules/urijs": { "version": "1.19.11", "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", - "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", + "dev": true }, "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "dev": true, "engines": { "node": ">= 4" } }, + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "dev": true, + "dependencies": { + "builtins": "^1.0.3" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -3267,6 +2472,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.4", @@ -3281,12 +2487,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -3320,57 +2520,30 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } } } diff --git a/package.json b/package.json index 58b0d15..3a01291 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "main": "./rules/json-ruleset.yaml", "type": "module", "scripts": { - "test": "./node_modules/.bin/eslint **/*.js test/ && ./node_modules/.bin/mocha --file ./test/testsSetup.js 'test/*.test.js' 'test/utilsTests/*.test.js' --timeout 10000", - "lint": "./node_modules/.bin/eslint **/*.js test/", + "test": "./node_modules/.bin/spectral lint examples/valid/* -r ./.spectral.yml", "prepare": "husky install" }, "repository": { @@ -18,13 +17,15 @@ "api", "linting", "spectral", + "stoplight", "ruleset", "jsonapi" ], "author": "Jeff Marquez (https://www.linkedin.com/in/jeffmarquez)", "contributors": [ "Ali Fazal (https://ca.linkedin.com/in/ali-fazal-424904140)", - "Ananya Poddar" + "Ananya Poddar", + "Anthony MacAllister" ], "license": "MIT", "bugs": { @@ -32,19 +33,7 @@ }, "homepage": "https://github.com/jmlue42/spectral-jsonapi-ruleset#readme", "devDependencies": { - "@stoplight/spectral-core": "^1.14.2", - "@stoplight/spectral-parsers": "^1.0.2", - "chai": "^4.3.6", - "chai-as-promised": "^7.1.1", - "eslint": "^8.24.0", - "eslint-plugin-mocha": "^10.1.0", - "husky": "^8.0.1", - "jsonpath-plus": "^7.2.0", - "mocha": "^10.0.0", - "sinon": "^17.0.1" - }, - "dependencies": { - "@stoplight/spectral-formats": "^1.4.0", - "@stoplight/spectral-functions": "^1.7.1" + "@stoplight/spectral-cli": "^6.11.0", + "husky": "^8.0.3" } } diff --git a/rules/jsonapi-content-negotiation-clients.js b/rules/jsonapi-content-negotiation-clients.js deleted file mode 100644 index 9e794c1..0000000 --- a/rules/jsonapi-content-negotiation-clients.js +++ /dev/null @@ -1,26 +0,0 @@ -// Content Negotiation - Client Responsibilities - https://jsonapi.org/format/1.0/#content-negotiation-clients - -// All rules in this file MUST have corresponding tests - -import { enumeration } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#content-negotiation-clients', - rules: { - 'request-content-type': { - description: 'All JSON:API request bodies MUST be received with the header Content-Type: application/vnd.api+json', - message: '{{path}} - {{description}}', - severity: 'error', - given: '$.paths..requestBody.content', - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'application/vnd.api+json' - ] - } - } - } - } -}; diff --git a/rules/jsonapi-content-negotiation-ruleset.yaml b/rules/jsonapi-content-negotiation-ruleset.yaml deleted file mode 100644 index e26d357..0000000 --- a/rules/jsonapi-content-negotiation-ruleset.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Content Negotiation -# https://jsonapi.org/format/1.0/#content-negotiation - -# *-ruleset.yaml files generally SHOULD NOT contain any testable rules. -# all rules in this file MUST have corresponding tests - -extends: - - jsonapi-content-negotiation-clients.js - - jsonapi-content-negotiation-servers.js diff --git a/rules/jsonapi-content-negotiation-servers.js b/rules/jsonapi-content-negotiation-servers.js deleted file mode 100644 index 9e460b5..0000000 --- a/rules/jsonapi-content-negotiation-servers.js +++ /dev/null @@ -1,42 +0,0 @@ -// Content Negotiation - Client Responsibilities - https://jsonapi.org/format/1.0/#content-negotiation-servers - -// All rules in this file MUST have corresponding tests - -import { enumeration, truthy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#content-negotiation-servers', - rules: { - 'response-content-type': { - description: 'All JSON:API response bodies MUST be returned with the header Content-Type: application/vnd.api+json', - message: '{{path}} - {{description}}', - severity: 'error', - given: '$.paths..responses..content', - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'application/vnd.api+json' - ] - } - } - }, - '415-406-response-codes': { - description: 'Servers MUST document and support a 415 and 406 on all paths in case of invalid media types', - message: '{{path}} - {{description}}', - severity: 'error', - given: '$.paths..responses', - then: [ - { - field: '415', - function: truthy - }, - { - field: '406', - function: truthy - } - ] - } - } -}; diff --git a/rules/jsonapi-document-structure-jsonapi-object.js b/rules/jsonapi-document-structure-jsonapi-object.js deleted file mode 100644 index a251997..0000000 --- a/rules/jsonapi-document-structure-jsonapi-object.js +++ /dev/null @@ -1,70 +0,0 @@ -// Document Structure - Top Level - https://jsonapi.org/format/1.0/#document-jsonapi-object - -// All rules in this file MUST have corresponding tests - -import { schema, falsy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-jsonapi-object', - rules: { - 'jsonapi-object-schema': { - description: 'jsonapi object must match schema', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..properties[?(@property === 'jsonapi')]", - then: [ - { - function: schema, - functionOptions: { - schema: { - type: 'object', - required: [ - 'properties', - 'type', - 'additionalProperties' - ], - properties: { - type: { - type: 'string', - enum: ['object'] - }, - properties: { - type: 'object', - properties: { - version: { - type: 'object', - required: ['type'], - properties: { - type: { - type: 'string', - enum: ['string'] - } - } - }, - meta: { - type: 'object', - required: ['type'], - properties: { - type: { - type: 'string', - enum: ['object'] - }, - additionalProperties: { - type: 'boolean' - } - } - } - } - } - } - } - } - }, - { - field: 'additionalProperties', - function: falsy - } - ] - } - } -}; diff --git a/rules/jsonapi-document-structure-links.js b/rules/jsonapi-document-structure-links.js deleted file mode 100644 index 3db388f..0000000 --- a/rules/jsonapi-document-structure-links.js +++ /dev/null @@ -1,63 +0,0 @@ -// Document Structure - Links - https://jsonapi.org/format/1.0/#document-links - -// All rules in this file MUST have corresponding tests - -import { enumeration } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-links', - rules: { - 'links-object': { - description: 'The value of each links member MUST be an object (a “links object”)', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..properties[?(@property === 'links')]", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: ['object'] - } - } - }, - 'links-object-schema-type': { - description: 'A link must be represented as either a string containing the link\'s URL or an object', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..properties[?(@property === 'links')].properties.*", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: ['object', 'string'] - } - } - }, - 'links-object-schema-properties': { - description: 'An object (“link object”) which can contain the following members (href and meta)', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..properties[?(@property === 'links')].properties..properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: ['href', 'meta'] - } - } - }, - 'links-object-schema-properties-href': { - description: 'href is a string containing the link\'s URL', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..properties[?(@property === 'links')].properties..properties[?(@property === 'href')]", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: ['string'] - } - } - } - } -}; diff --git a/rules/jsonapi-document-structure-meta-information.js b/rules/jsonapi-document-structure-meta-information.js deleted file mode 100644 index aa31744..0000000 --- a/rules/jsonapi-document-structure-meta-information.js +++ /dev/null @@ -1,24 +0,0 @@ -// Document Structure - Meta Information - https://jsonapi.org/format/1.0/#document-meta - -// All rules in this file MUST have corresponding tests - -import { enumeration } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-meta', - rules: { - 'meta-object-schema': { - description: 'The value of each meta member MUST be an object (a “meta object”)', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..properties[?(@property === 'meta')]", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: ['object'] - } - } - } - } -}; diff --git a/rules/jsonapi-document-structure-resource-attributes.js b/rules/jsonapi-document-structure-resource-attributes.js deleted file mode 100644 index ee187b1..0000000 --- a/rules/jsonapi-document-structure-resource-attributes.js +++ /dev/null @@ -1,154 +0,0 @@ -// Document Structure - Resource Objects - https://jsonapi.org/format/1.0/#document-resource-object-attributes - -// All rules in the file MUST have corresponding tests - -import { enumeration, pattern, falsy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-resource-object-attributes', - rules: { - - /** - * Verifies that the `attributes` member in each single `Resource Object` is of type `object`. - * This rule is crucial for maintaining consistency in representing some of the resource's data. - */ - 'document-structure-resource-single-attributes-type': { - description: '`attributes` member in a single `Resource Object` MUST be of type `object`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.attributes", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - }, - - /** - * Ensures that the `attributes` member in a single `Resource Object` does not - * contain any foreign keys, which is stated 'SHOULD NOT appear as attributes' - * per JSON:API v1.0. - */ - 'document-structure-resource-single-attributes-no-foreign-keys': { - description: '`attributes` member in a single `Resource Object` SHOULD NOT contain any foreign keys', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties", - then: { - field: '@key', - function: pattern, - functionOptions: { - notMatch: '.*_id$' - } - } - }, - - /** - * Ensures that the `attributes` member in a single `Resource Object` does not - * contain a `relationships` member, which is stated 'MUST NOT cotain a `relationships` - * member' per JSON:API v1.0. This rule will also conduct a check for deeply nested - * objects to ensure that a `relationships` member is not present. - */ - 'document-structure-resource-single-attributes-no-relationships-member': { - description: '`attributes` member in a single `Resource Object` MUST NOT contain a `relationships` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.attributes..[?(@property == 'relationships')]", - then: { - function: falsy - } - }, - - /** - * Ensures that the `attributes` member in a single `Resource Object` does not - * contain a `links` member, which is stated 'MUST NOT cotain a `links` member' - * per JSON:API v1.0. This rule will also conduct a check for deeply nested - * objects to ensure that a `links` member is not present. - */ - 'document-structure-resource-single-attributes-no-links-member': { - description: '`attributes` member in a single `Resource Object` MUST NOT contain a `links` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.attributes..[?(@property == 'links')]", - then: { - function: falsy - } - }, - - /** - * Verifies that the `attributes` member in an array of `Resource Objects` is of type `object`. - * This rule is crucial for maintaining consistency in representing some of the resource's data. - */ - 'document-structure-resource-array-attributes-type': { - description: '`attributes` member in an array of `Resource Objects` MUST be of type `object`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.attributes", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - }, - - /** - * Ensures that the `attributes` member in an array of `Resource Objects` does not - * contain any foreign keys, which is stated 'SHOULD NOT appear as attributes' - * per JSON:API v1.0. - */ - 'document-structure-resource-array-attributes-no-foreign-keys': { - description: '`attributes` member in an array of `Resource Objects` SHOULD NOT contain any foreign keys', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.attributes.properties", - then: { - field: '@key', - function: pattern, - functionOptions: { - notMatch: '.*_id$' - } - } - }, - - /** - * Ensures that the `attributes` member in an array of `Resource Objects` does not - * contain a `relationships` member, which is stated 'MUST NOT cotain a `relationships` - * member' per JSON:API v1.0. This rule will also conduct a check for deeply nested - * objects to ensure that a `relationships` member is not present. - */ - 'document-structure-resource-array-attributes-no-relationships-member': { - description: '`attributes` member in an array of `Resource Objects` MUST NOT contain a `relationships` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.attributes..[?(@property == 'relationships')]", - then: { - function: falsy - } - }, - - /** - * Ensures that the `Attributes` member in an array of `Resource Objects` does not - * contain a `links` member, which is stated 'MUST NOT cotain a `links` member' - * per JSON:API v1.0. This rule will also conduct a check for deeply nested - * objects to ensure that a `links` member is not present. - */ - 'document-structure-resource-array-attributes-no-links-member': { - description: '`attributes` member in an array of `Resource Objects` MUST NOT contain a `links` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.attributes..[?(@property == 'links')]", - then: { - function: falsy - } - } - - } -}; diff --git a/rules/jsonapi-document-structure-resource-attributes.yaml.old b/rules/jsonapi-document-structure-resource-attributes.yaml.old deleted file mode 100644 index 1c329a5..0000000 --- a/rules/jsonapi-document-structure-resource-attributes.yaml.old +++ /dev/null @@ -1,30 +0,0 @@ -# Document Structure - Meta Information -# https://jsonapi.org/format/#document-resource-object-attributes - -# all rules in this file MUST have corresponding tests - -rules: - attributes-object-type: - description: "The value of the attributes key MUST be an object (an “attributes object”)" - documentationUrl: https://jsonapi.org/format/#document-resource-object-attributes - message: "{{path}} - {{description}}" - severity: error - given: $..properties[?(@property === 'attributes')] - then: - field: 'type' - function: enumeration - functionOptions: - values: - - object - - attributes-object-properties: - description: "Any object that constitutes or is contained in an attribute MUST NOT contain a relationships or links member." - documentationUrl: https://jsonapi.org/format/#document-resource-object-attributes - message: "{{path}} - {{description}}" - severity: error - given: $..properties[?(@property === 'attributes')].properties - then: - - field: 'relationships' - function: falsy - - field: 'links' - function: falsy diff --git a/rules/jsonapi-document-structure-resource-fields.js b/rules/jsonapi-document-structure-resource-fields.js deleted file mode 100644 index eabeb61..0000000 --- a/rules/jsonapi-document-structure-resource-fields.js +++ /dev/null @@ -1,33 +0,0 @@ -// Document Structure - Resource Objects - https://jsonapi.org/format/1.0/#document-resource-object-fields - -// All rules in the file MUST have corresponding tests - -import { falsy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-resource-object-fields', - rules: { - - /** - * Ensures that no fields are directly named `type` or `id`, which are reserved per - * JSON:API v1.0 - */ - 'document-structure-resource-fields-no-type-or-id': { - description: 'Ensure that `type` and `id` are not used as field names in `attributes` or `relationships`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$.paths..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data..[?(@property == 'attributes' || @property == 'relationships')].properties", - then: [ - { - field: 'id', - function: falsy - }, - { - field: 'type', - function: falsy - } - ] - } - - } -}; diff --git a/rules/jsonapi-document-structure-resource-identification.js b/rules/jsonapi-document-structure-resource-identification.js deleted file mode 100644 index 5d898c0..0000000 --- a/rules/jsonapi-document-structure-resource-identification.js +++ /dev/null @@ -1,156 +0,0 @@ -// Document Structure - Resource Objects - Identification - https://jsonapi.org/format/1.0/#document-resource-object-identification - -// All rules in the file MUST have corresponding tests - -import { enumeration, truthy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-resource-object-identification', - rules: { - - /** - * Ensures that a single `Resource Object` contains a `id` member. - */ - 'document-structure-resource-single-identification-id-member': { - description: 'A single `Resource Object` MUST contain an `id` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: [ - "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses')]..content['application/vnd.api+json'].schema.properties.data.properties", - "$..[?(@property == 'put' || @property == 'patch')]..[?(@property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties" - ], - then: { - field: 'id', - function: truthy - } - }, - - /** - * Ensures that a single `Resource Object` contains a `id` member. - */ - 'document-structure-resource-single-identification-id-type': { - description: 'A single `Resource Object` `id` member MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: [ - "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses')]..content['application/vnd.api+json'].schema.properties.data.properties.id", - "$..[?(@property == 'put' || @property == 'patch')]..[?(@property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.id" - ], - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Ensures that a single `Resource Object` contains a `type` member. - */ - 'document-structure-resource-single-identification-type-member': { - description: 'A single `Resource Object` MUST contain an `type` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties", - then: { - field: 'type', - function: truthy - } - }, - - /** - * Ensures that a single `Resource Object` contains a `type` member. - */ - 'document-structure-resource-single-identification-type-type': { - description: 'A single `Resource Object` `type` member MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.type", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Ensures that an array of `Resource Objects` contains a `id` member. - */ - 'document-structure-resource-array-identification-id-member': { - description: 'An array of `Resource Objects` MUST contain an `id` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: [ - "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses')]..content['application/vnd.api+json'].schema.properties.data.items.properties", - "$..[?(@property == 'put' || @property == 'patch')]..[?(@property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties" - ], - then: { - field: 'id', - function: truthy - } - }, - - /** - * Ensures that an array of `Resource Objects` contains a `id` member. - */ - 'document-structure-resource-array-identification-id-type': { - description: 'An array of `Resource Objects` `id` member MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: [ - "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses')]..content['application/vnd.api+json'].schema.properties.data.items.properties.id", - "$..[?(@property == 'put' || @property == 'patch')]..[?(@property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.id" - ], - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Ensures that an array of `Resource Objects` contains a `type` member. - */ - 'document-structure-resource-array-identification-type-member': { - description: 'An array of `Resource Objects` MUST contain an `type` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties", - then: { - field: 'type', - function: truthy - } - }, - - /** - * Ensures that an array of `Resource Objects` contains a `type` member. - */ - 'document-structure-resource-array-identification-type-type': { - description: 'An array of `Resource Objects` `type` member MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.type", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - } - - } -}; diff --git a/rules/jsonapi-document-structure-resource-identification.yaml.old b/rules/jsonapi-document-structure-resource-identification.yaml.old deleted file mode 100644 index 2a4c751..0000000 --- a/rules/jsonapi-document-structure-resource-identification.yaml.old +++ /dev/null @@ -1,33 +0,0 @@ -# Document Structure - Meta Information -# https://jsonapi.org/format/#document-resource-object-identification - -# all rules in this file MUST have corresponding tests - -rules: - resource-identification-property: - description: "Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings." - documentationUrl: https://jsonapi.org/format/#document-resource-object-identification - message: "{{path}} - {{description}}" - severity: error - given: $..properties[?(@property === 'data' || @property === 'included')]..allOf.*.properties - then: - field: "@key" - function: enumeration - functionOptions: - values: - - type - - id - - resource-identification-type: - description: "Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings." - documentationUrl: https://jsonapi.org/format/#document-resource-object-identification - message: "{{path}} - {{description}}" - severity: error - given: $..properties[?(@property === 'data' || @property === 'included')]..allOf.*.properties[?(@property === 'id' || @property === 'type')] - then: - field: "type" - function: enumeration - functionOptions: - values: - - string - diff --git a/rules/jsonapi-document-structure-resource-identifier-object.js b/rules/jsonapi-document-structure-resource-identifier-object.js deleted file mode 100644 index 4c72666..0000000 --- a/rules/jsonapi-document-structure-resource-identifier-object.js +++ /dev/null @@ -1,338 +0,0 @@ -// Document Structure - Resource Identifier Object - https://jsonapi.org/format/1.0/#document-resource-identifier-objects - -// All rules in this file MUST have corresponding tests - -import { schema, enumeration } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-resource-identifier-objects', - rules: { - - // explicitly defined - 'relationships-data-object-explicit': { - description: '\'relationships..data\' properties MUST be an object or an array of objects with an id and type property', - message: '{{path}} - {{description}}', - severity: 'error', - resolved: true, - given: "$..*[?(@property === 'relationships')]..properties.data[?(@property === 'type' && (@ === 'object' || @ === 'array'))]^", - then: [ - { - function: schema, - functionOptions: { - schema: { - 'oneOf': [ - { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'required': { - 'type': 'array', - 'items': [ - { - 'type': 'string' - }, - { - 'type': 'string' - } - ] - }, - 'properties': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'pattern': { - 'type': 'string' - }, - 'example': { - 'type': 'string' - } - }, - 'required': [ - 'type' - ] - }, - 'type': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'enum': { - 'type': 'array', - 'items': [ - { - 'type': 'string' - } - ] - } - }, - 'required': [ - 'type' - ] - } - }, - 'required': [ - 'id', - 'type' - ] - } - }, - 'required': [ - 'type', - 'required', - 'properties' - ] - }, - { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'items': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'required': { - 'type': 'array', - 'items': [ - { - 'type': 'string' - }, - { - 'type': 'string' - } - ] - }, - 'properties': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - } - }, - 'required': [ - 'type' - ] - }, - 'type': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - } - }, - 'required': [ - 'type' - ] - } - }, - 'required': [ - 'id', - 'type' - ] - } - }, - 'required': [ - 'type', - 'required', - 'properties' - ] - } - }, - 'required': [ - 'type', - 'items' - ] - } - ] - } - } - } - ] - }, - - // composed using allOf - 'relationships-data-object-composed': { - description: '\'relationships..data\' properties MUST be an object or an array of objects with an id and type property', - message: '{{path}} - {{description}}', - severity: 'error', - resolved: true, - given: "$..*[?(@property === 'relationships')]..properties.data..allOf", - then: [ - { - function: schema, - functionOptions: { - schema: { - 'contains': { - 'oneOf': [ - { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'required': { - 'type': 'array', - 'items': [ - { - 'type': 'string' - }, - { - 'type': 'string' - } - ] - }, - 'properties': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'pattern': { - 'type': 'string' - }, - 'example': { - 'type': 'string' - } - }, - 'required': [ - 'type' - ] - }, - 'type': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'enum': { - 'type': 'array', - 'items': [ - { - 'type': 'string' - } - ] - } - }, - 'required': [ - 'type' - ] - } - }, - 'required': [ - 'id', - 'type' - ] - } - }, - 'required': [ - 'type', - 'required', - 'properties' - ] - }, - { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'items': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - }, - 'required': { - 'type': 'array', - 'items': [ - { - 'type': 'string' - }, - { - 'type': 'string' - } - ] - }, - 'properties': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - } - }, - 'required': [ - 'type' - ] - }, - 'type': { - 'type': 'object', - 'properties': { - 'type': { - 'type': 'string' - } - }, - 'required': [ - 'type' - ] - } - }, - 'required': [ - 'id', - 'type' - ] - } - }, - 'required': [ - 'type', - 'required', - 'properties' - ] - } - }, - 'required': [ - 'type', - 'items' - ] - } - ] - } - } - } - } - ] - }, - 'relationships-data-allowed-fields': { - description: 'Resource Identifier Objects MAY only contain id, type, and meta fields', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..*[?(@property === 'relationships')]..properties.data..properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: ['id', 'type', 'meta'] - } - } - } - } -}; diff --git a/rules/jsonapi-document-structure-resource-object-ruleset.yaml b/rules/jsonapi-document-structure-resource-object-ruleset.yaml deleted file mode 100644 index 44a0016..0000000 --- a/rules/jsonapi-document-structure-resource-object-ruleset.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# Document Structure -# https://jsonapi.org/format/1.0/#document-resource-objects - -# *-ruleset.yaml files generally SHOULD NOT contain any testable rules. -# all rules in this file MUST have corresponding tests. - -extends: - # - jsonapi-document-structure-identification.js - # - jsonapi-document-structure-fields.js - # - jsonapi-document-structure-attributes.js - # - jsonapi-document-structure-relationships.js - # - jsonapi-document-structure-related-resource-links.js - # - jsonapi-document-structure-resource-linkage.js - # - jsonapi-document-structure-resource-links.js diff --git a/rules/jsonapi-document-structure-resource-object.yaml.old b/rules/jsonapi-document-structure-resource-object.yaml.old deleted file mode 100644 index acf98eb..0000000 --- a/rules/jsonapi-document-structure-resource-object.yaml.old +++ /dev/null @@ -1,104 +0,0 @@ -# Document Structure - Resource Object -# https://jsonapi.org/format/#document-resource-objects - -# all rules in this file MUST have corresponding tests - -rules: - resource-object-properties-object: - description: "Must follow resource object properties" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'object')]^.properties - then: - field: "@key" - function: enumeration - functionOptions: - values: - - type - - id - - attributes - - relationships - - links - - meta - - resource-object-properties-array: - description: "Must follow resource object properties" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'array')]^..allOf.*.properties - then: - field: "@key" - function: enumeration - functionOptions: - values: - - type - - id - - attributes - - relationships - - links - - meta - - resource-object-properties-type-object: - description: "Top level members of resource object must be of type object" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'object')]^.properties[?(@property === 'attributes' || @property === 'relationships' || @property === 'links' || @property === 'meta')] - then: - field: "type" - function: enumeration - functionOptions: - values: - - object - - resource-object-properties-type-array: - description: "Top level members of resource object must be of type object" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'array')]^..allOf.*.properties[?(@property === 'attributes' || @property === 'relationships' || @property === 'links' || @property === 'meta')] - then: - field: "type" - function: enumeration - functionOptions: - values: - - object - - resource-object-properties-included-object: - description: "A resource object must contain the top-level members type and id" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths.*.[?(@property === 'requestBody' && @parentProperty !== 'post' || @property === 'responses')]..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'object')]^.properties - then: - - field: 'type' - function: truthy - - field: 'id' - function: truthy - - resource-object-properties-included-array: - description: "A resource object must contain the top-level members type and id" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths.*.[?(@property === 'requestBody' && @parentProperty !== 'post' || @property === 'responses')]..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'array')]^..allOf.*.properties - then: - - field: 'type' - function: truthy - - field: 'id' - function: truthy - - - #ccording to https://jsonapi.org/format/#crud, this requestBody should only be a single resource object - resource-object-id-exception: - description: "The id member is not required when the resource object originates at the client and represents a new resource to be created on the server" - documentationUrl: https://jsonapi.org/format/#document-resource-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..[?(@property === 'post')][?(@property === 'requestBody')]..schema.properties[?(@property === 'data' || @property === 'included')].properties - then: - field: 'type' - function: truthy - diff --git a/rules/jsonapi-document-structure-resource-objects.js b/rules/jsonapi-document-structure-resource-objects.js deleted file mode 100644 index 43c46b5..0000000 --- a/rules/jsonapi-document-structure-resource-objects.js +++ /dev/null @@ -1,315 +0,0 @@ -// Document Structure - Resource Objects - https://jsonapi.org/format/1.0/#document-resource-objects - -// All rules in the file MUST have corresponding tests - -import { enumeration, length, truthy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-resource-objects', - rules: { - - /** - * Ensures that a `Resource Object` is of type `object` or `array` - */ - 'document-structure-resource-objects-type': { - description: 'A `Resource Object` MUST be of type `object` or `array`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object', - 'array' - ] - } - } - }, - - /** - * Checks the presence of 'id' and 'type' within a single `Resource Object`. - */ - 'document-structure-resource-objects-single-structure': { - description: 'A single `Resource Object` MUST only contain the specified members', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'id', - 'type', - 'attributes', - 'relationships', - 'links', - 'meta' - ] - } - } - }, - - /** - * Ensures that the single `Resource Object` contains an appropriate number of members. - * This rule checks that a single `Resource Object` has a minmum of two members and a - * maximum of 6 members. This will even include for when an `id` member is not required - * Exception because when creating a new resource, typically the `attributes` and/or - * `relationships` objects are provided to supply the data needed to create the resource. - */ - 'document-structure-resource-objects-single-structure-length': { - description: 'A single `Resource Object` MAY contain between two or six specified members', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties", - then: { - function: length, - functionOptions: { - min: 2, - max: 6 - } - } - }, - - /** - * Ensures that a single `Resource Object` has a `type` member. - */ - 'document-structure-resource-objects-single-type-required': { - description: 'A single `Resource Object` MUST contain `type` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties", - then: { - field: 'type', - function: truthy - } - }, - - /** - * Ensures that a single `Resource Object` has a `id` member for the specific - * targeted HTTP methods: GET, DELETE, PUT, PATCH. - * - * HTTP method 'POST' will not have an `id` member. When a client is sending a request - * to create a new resource on the server, the `id` of the resource is not yet known, as - * it is usually generated by the server. In such cases, the `Resource Object` in the - * request body will not include an `id` member. This is common in `POST` requests where - * a new resource is being added. - */ - 'document-structure-resource-objects-single-id-required': { - description: 'A single `Resource Object` MUST contain `id` member for HTTP methods: GET, DELETE, PUT, PATCH', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties", - then: { - field: 'id', - function: truthy - } - }, - - /** - * Verifies that the `id` member in each single `Resource Object` is of type `string`. - * This rule is crucial for maintaining consistency in `Resource Object` indentifiers. - */ - 'document-structure-resource-objects-single-id-type': { - description: '`id` member in a single `Resource Object` MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.id", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Verifies that the `type` member in each single `Resource Object` is of type `string`. - * This rule is to assist with ensuring a single `Resource Object` share a common - * attributes and relationships. - */ - 'document-structure-resource-objects-single-type-type': { - description: '`type` member in a single `Resource Object` MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.type", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Verifies that the `attributes` member in each single `Resource Object` is of type `object`. - * This rule is crucial for maintaining consistency in representing some of the resource's data. - */ - 'document-structure-resource-objects-single-attributes-type': { - description: '`attributes` member in a single `Resource Object` MUST be of type `object`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.properties.attributes", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - }, - - /** - * Checks the presence of 'id' and 'type' within an array of `Resource Objects`. - */ - 'document-structure-resource-objects-array-structure': { - description: 'An array of `Resource Objects` MUST only contain the specified members', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'id', - 'type', - 'attributes', - 'relationships', - 'links', - 'meta' - ] - } - } - }, - - /** - * Ensures that the an array of `Resource Objects` contains an appropriate number of members. - * This rule checks that an array of `Resource Objects` has a minmum of two members and a - * maximum of 6 members. This will even include for when an `id` member is not required - * Exception because when creating a new resource, typically the `attributes` and/or - * `relationships` objects are provided to supply the data needed to create the resource. - */ - 'document-structure-resource-objects-array-structure-length': { - description: 'An array of `Resource Objects` MAY contain between two or six specified members', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties", - then: { - function: length, - functionOptions: { - min: 2, - max: 6 - } - } - }, - - /** - * Ensures that an array of `Resource Objects` has a `type` member. - */ - 'document-structure-resource-objects-array-type-required': { - description: 'An array of `Resource Objects` MUST contain `type` member', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties", - then: { - field: 'type', - function: truthy - } - }, - - /** - * Ensures that an array of `Resource Objects` has a `id` member for the specific - * targeted HTTP methods: GET, DELETE, PUT, PATCH. - * - * HTTP method 'POST' will not have an `id` member. When a client is sending a request - * to create a new resource on the server, the `id` of the resource is not yet known, as - * it is usually generated by the server. In such cases, the `Resource Object` in the - * request body will not include an `id` member. This is common in `POST` requests where - * a new resource is being added. - */ - 'document-structure-resource-objects-array-id-required': { - description: 'An array of `Resource Objects` MUST contain `id` member for HTTP methods: GET, DELETE, PUT, PATCH', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties", - then: { - field: 'id', - function: truthy - } - }, - - /** - * Verifies that the `id` member in an array of `Resource Objects` is of type `string`. - * This rule is crucial for maintaining consistency in `Resource Object` indentifiers. - */ - 'document-structure-resource-objects-array-id-type': { - description: '`id` member in an array of `Resource Objects` MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.id", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Verifies that the `type` member in an array of `Resource Objects` is of type `string`. - * This rule is to assist with ensuring aa array of `Resource Objects` share a common - * attributes and relationships. - */ - 'document-structure-resource-objects-array-type-type': { - description: '`type` member in an array of `Resource Objects` MUST be of type `string`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.type", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Verifies that the `attributes` member in an array of `Resource Objects` is of type `object`. - * This rule is crucial for maintaining consistency in representing some of the resource's data. - */ - 'document-structure-resource-objects-array-attributes-type': { - description: '`attributes` member in an array of `Resource Objects` MUST be of type `object`', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$..[?(@property == 'get' || @property == 'delete' || @property == 'put' || @property == 'patch' || @property == 'post')]..[?(@property == 'responses' || @property == 'requestBody')]..content['application/vnd.api+json'].schema.properties.data.items.properties.attributes", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - } - - - } -}; diff --git a/rules/jsonapi-document-structure-ruleset.yaml b/rules/jsonapi-document-structure-ruleset.yaml deleted file mode 100644 index 4d13aea..0000000 --- a/rules/jsonapi-document-structure-ruleset.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Document Structure -# https://jsonapi.org/format/1.0/#document-structure - -# *-ruleset.yaml files generally SHOULD NOT contain any testable rules. -# all rules in this file MUST have corresponding tests. - -extends: - - jsonapi-document-structure-top-level.js - # - jsonapi-document-structure-resource-object-ruleset.yaml - - jsonapi-document-structure-resource-identifier-object.js - # - jsonapi-document-structure-compound-document.js - - jsonapi-document-structure-meta-information.js - - jsonapi-document-structure-links.js - - jsonapi-document-structure-jsonapi-object.js - - jsonapi-document-structure-resource-objects.js - - jsonapi-document-structure-resource-identification.js - - jsonapi-document-structure-resource-attributes.js - - jsonapi-document-structure-resource-fields.js diff --git a/rules/jsonapi-document-structure-top-level.js b/rules/jsonapi-document-structure-top-level.js deleted file mode 100644 index e61c02e..0000000 --- a/rules/jsonapi-document-structure-top-level.js +++ /dev/null @@ -1,66 +0,0 @@ -// Document Structure - Top Level - https://jsonapi.org/format/1.0/#document-top-level - -// All rules in this file MUST have corresponding tests - -import { enumeration, truthy, falsy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#document-top-level', - rules: { - 'top-level-json-object': { - description: 'A JSON object MUST be at the root of every JSON:API request/response body containing data.', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$.paths..content[?(@property === 'application/vnd.api+json')].schema", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - }, - 'top-level-json-properties': { - description: 'Must follow top level JSON:API document properties.', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'data', - 'meta', - 'errors', - 'links', - 'included', - 'jsonapi' - ] - } - } - }, - 'top-level-json-properties-included': { - description: '\'data\' property must exist if included is returned', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'included')]^", - then: { - field: 'data', - function: truthy - } - }, - 'top-level-json-properties-errors': { - description: '\'data\' property must not exist if errors is returned', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'errors')]^", - then: { - field: 'data', - function: falsy - } - } - } -}; diff --git a/rules/jsonapi-errors-error-object.js b/rules/jsonapi-errors-error-object.js deleted file mode 100644 index e65aa7a..0000000 --- a/rules/jsonapi-errors-error-object.js +++ /dev/null @@ -1,341 +0,0 @@ -// Errors - Error Objects - https://jsonapi.org/format/#error-objects - -// All rules in the file MUST have corresponding tests - -import { enumeration, length } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/#error-objects', - rules: { - - /** - * Checks that error objects are structured correctly within the response. - * Specifically, it ensures that the 'errors' key is an array, adhering - * to the JSON:API specification. - */ - 'errors-error-objects-array-structure': { - description: '`error` objects MUST be returned in an array under `errors` key', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]]", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'array' - ] - } - } - }, - - /** - * Validates the structure of error objects within the 'errors' array. - * It ensures that error objects only contain specified members as per - * JSON:API guidelines. - */ - 'errors-error-objects-object-structure': { - description: '`error` objects MUST only contain the specified members', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'id', - 'links', - 'status', - 'code', - 'title', - 'detail', - 'source', - 'meta' - ] - } - } - }, - - /** - * Ensures the error objects contain an appropriate number of members. - * This rule checks that each error object has at least one and no more - * than eight members. - */ - 'errors-error-objects-object-structure-length': { - description: '`error` objects MAY contain between one or eight specified members', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items", - then: { - field: 'properties', - function: length, - functionOptions: { - min: 1, - max: 8 - } - } - }, - - /** - * Verifies that the 'id' member in each error object is of type 'string'. - * This rule is crucial for maintaining consistency in error object identifiers. - */ - 'errors-error-objects-items-id-type': { - description: '`id` member in `errors` array MUST by of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.id", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Ensures that the 'links' member in each error object is of type 'object'. - * This rule checks the structure of 'links' objects within error responses. - */ - 'errors-error-objects-items-links-type': { - description: '`links` member in `errors` array MUST by of type `object`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.links", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - }, - - /** - * Checks the members of 'links' objects in error responses. - * It validates that 'links' object only contain the 'about' and/or 'type' members. - */ - 'errors-error-objects-items-links-members': { - description: '`links` object MAY contain only one of the following members: `about` and/or `type`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.links.properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'about' - ] - } - } - }, - - /** - * Validates the number of members in 'links' objects within error objects. - * Ensures that each 'links' object contains only one or two specified members. - */ - 'errors-error-objects-items-links-structure-length': { - description: '`links` objects MAY only contain the specified members and not be empty', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.links", - then: { - field: 'properties', - function: length, - functionOptions: { - min: 1, - max: 1 - } - } - }, - - /** - * Ensures the 'status' member in error objects is of type 'string'. - * This rule checks the format of HTTP status codes in error responses. - */ - 'errors-error-objects-items-status-type': { - description: '`status` member in `errors` array MUST by of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.status", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Validates that the 'code' member in error objects is a string. - * This rule helps in standardizing error codes within error responses. - */ - 'errors-error-objects-items-code-type': { - description: '`code` member in `errors` array MUST by of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.code", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Ensures that the 'title' member in error objects is of type 'string'. - * This rule checks the format of error titles, ensuring they are textual descriptions. - */ - 'errors-error-objects-items-title-type': { - description: '`title` member in `errors` array MUST by of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.title", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Validates that the 'detail member in error objects is a string. - * This rule ensures that error details provide a clear textual explanation. - */ - 'errors-error-objects-items-detail-type': { - description: '`detail` member in `errors` array MUST by of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.detail", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Checks that the 'source' member in error objects is of type 'object'. - * This rule validates the structure of 'source' objects, which pinpoint the origin of errors. - */ - 'errors-error-objects-items-source-type': { - description: '`source` member in `errors` array MUST by of type `object`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.source", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'object' - ] - } - } - }, - - /** - * Validates the members of 'source' objects in error responses. - * Ensures 'source' objects contain only 'pointer', 'parameter', and/or 'header' members. - */ - 'errors-error-objects-items-source-members': { - description: '`source` object SHOULD contain only one of the following members: `pointer`, `parameter` and/or `header`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.source.properties", - then: { - field: '@key', - function: enumeration, - functionOptions: { - values: [ - 'pointer', - 'parameter' - ] - } - } - }, - - /** - * Ensures that the 'pointer' member in 'source' objects is a string. - * This rule checks the format of 'pointer', which should indicate the exact location of the error. - */ - 'errors-error-objects-items-source-pointer-type': { - description: '`pointer` member in the `source` object MUST be of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.source.properties.pointer", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Validates the 'parameter' member in 'source' objects as a string. - * This rule is important for correctly identifying query parameters related to errors. - */ - 'errors-error-objects-items-source-parameter-type': { - description: '`parameter` member in the `source` object MUST be of type `string`', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.source.properties.parameter", - then: { - field: 'type', - function: enumeration, - functionOptions: { - values: [ - 'string' - ] - } - } - }, - - /** - * Validates the number of members in 'source' objects within error objects. - * Ensures that each 'source' object has between one and three members. - */ - 'errors-error-objects-items-source-structure-length': { - description: '`source` object MUST be between one or three members and not be empty', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')]..[*[?(@property === 'errors')]].items.properties.source", - then: { - field: 'properties', - function: length, - functionOptions: { - min: 1, - max: 2 - } - } - } - - } - -}; diff --git a/rules/jsonapi-errors-error-object.yaml.old b/rules/jsonapi-errors-error-object.yaml.old deleted file mode 100644 index 6147552..0000000 --- a/rules/jsonapi-errors-error-object.yaml.old +++ /dev/null @@ -1,115 +0,0 @@ -# Errors - Error Object -# https://jsonapi.org/format/#errors - -# all rules in this file MUST have corresponding tests - -rules: - error-object-type: - description: "Error objects MUST be returned as an array keyed by errors in the top level of a JSON:API document." - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors] - then: - field: "type" - function: enumeration - functionOptions: - values: - - array - - error-object-properties: - description: "Must follow error object properties." - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties - then: - field: "@key" - function: enumeration - functionOptions: - values: - - id - - links - - status - - code - - title - - detail - - source - - meta - - error-object-members-type-object: - description: "Links, source, and meta (if included) must be an object" - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[?(@property === 'links' || @property === 'meta' || @property === 'source')] - then: - field: "type" - function: enumeration - functionOptions: - values: - - object - - error-object-members-type-string: - description: "Status, code, title, detail, and source members (if included) must be strings" - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[?(@property === 'status' || @property === 'code' || @property === 'title' || @property === 'detail')] - then: - field: "type" - function: enumeration - functionOptions: - values: - - string - - error-object-links-properties: - description: "Links object inside an error object must include an 'about' member " - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[links].properties - then: - field: "about" - function: truthy - - error-object-source-properties: - description: "Must follow source object properties" - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[source].properties - then: - field: "@key" - function: enumeration - functionOptions: - values: - - pointer - - parameter - - error-object-source-parameter-type: - description: "Parameter, if included in source object, must be of type string" - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[source].properties[parameter] - then: - field: "type" - function: enumeration - functionOptions: - values: - - string - - error-object-source-pointer-type: - description: "Pointer, if included in source object, must be of type string or array" - documentationUrl: https://jsonapi.org/format/#error-objects - message: "{{path}} - {{description}}" - severity: error - given: $.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[source].properties[pointer] - then: - field: "type" - function: enumeration - functionOptions: - values: - - string - - array diff --git a/rules/jsonapi-errors-processing-errors.js b/rules/jsonapi-errors-processing-errors.js deleted file mode 100644 index f7931d7..0000000 --- a/rules/jsonapi-errors-processing-errors.js +++ /dev/null @@ -1,60 +0,0 @@ -// Errors - Error Objects - https://jsonapi.org/format/#error-processing - -// All rules in the file MUST have corresponding tests - -import { enumeration, truthy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/#error-processing', - rules: { - - /** - * Checks that error objects array contains the JSON Schema keyword - * `maxItems` to enforce one status code being returned when multiple - * probblems are encountered. - * - * It's important to note that while this rule ensures the document - * includes the `maxItems` keyword, it doesn't enforce the actual behavior - * in your API's code. Essentially you will want to ensure separately - * that the API implementation respects this specific contraint. - */ - 'errors-processing-errors-array-max-items': { - description: 'When multiple problems are encountered one status code needs to be returned', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')].content['application/vnd.api+json'].schema.properties.[?(@property === 'errors')]", - then: { - field: 'maxItems', - function: truthy - } - }, - - /** - * Checks that error objects array contains the JSON Schema keyword - * `maxItems` and have the appropraite value which is to enforce - * one status code being returned when multiple probblems are encountered. - * - * It's important to note that while this rule ensures the document - * includes the `maxItems` keyword, it doesn't enforce the actual behavior - * in your API's code. Essentially you will want to ensure separately - * that the API implementation respects this specific contraint. - */ - 'errors-processing-errors-array-max-items-value': { - description: 'When multiple problems are encountered one status code needs to be returned', - message: '{{path}} - {{description}}', - severity: 'error', - given: "$..[?(@property >= '400' && @property <= '599')].content['application/vnd.api+json'].schema.properties.[?(@property === 'errors')]", - then: { - field: 'maxItems', - function: enumeration, - functionOptions: { - values: [ - 1 - ] - } - } - } - - } - -}; diff --git a/rules/jsonapi-errors-ruleset.yaml b/rules/jsonapi-errors-ruleset.yaml deleted file mode 100644 index c0ba1c1..0000000 --- a/rules/jsonapi-errors-ruleset.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Errors -# https://jsonapi.org/format/#error-objects - -# *-ruleset.yaml files generally SHOULD NOT contain any testable rules. -# all rules in this file MUST have corresponding tests. - -extends: - - jsonapi-errors-error-object.js - - jsonapi-errors-processing-errors.js \ No newline at end of file diff --git a/rules/jsonapi-fetching-data-fetching-resources.js b/rules/jsonapi-fetching-data-fetching-resources.js deleted file mode 100644 index 9d68dd4..0000000 --- a/rules/jsonapi-fetching-data-fetching-resources.js +++ /dev/null @@ -1,82 +0,0 @@ -// Fetching Data - Fetching Resources - https://jsonapi.org/format/1.0/#fetching-resources - -// All rules in the file MUST have corresponding tests - -import { truthy } from '@stoplight/spectral-functions'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#fetching-resources', - rules: { - - /** - * Ensure top-level resposnes include a `self` link in a `links` object - */ - 'fetching-data-fetching-resources-top-level-links': { - description: 'Ensure top-level resposnes include a `self` link in a `links` object', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$.paths.*.*.responses.*.content['application/vnd.api+json'].schema.properties.links.properties", - then: { - field: 'self', - function: truthy - } - }, - - /** - * Checks for the presence of a `self` link in each resource object within a single responses - */ - 'fetching-data-fetching-resources-single-level-self-link': { - description: 'Ensure single resource object responses include a `self` link in a `links` object', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$.paths.*.*.responses.*.content['application/vnd.api+json'].schema.properties.data.properties.links.properties", - then: { - field: 'self', - function: truthy - } - }, - - /** - * Ensures that relationship objects within each resource in responses has a `related` link - */ - 'fetching-data-fetching-resources-single-relationship-level-related-link': { - description: 'Ensure relationship objects in responses include a `related` link', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$.paths.*.*.responses.*.content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.*.properties", - then: { - field: 'related', - function: truthy - } - }, - - /** - * Checks for the presence of a `self` link in each resource object within array responses - */ - 'fetching-data-fetching-resources-array-level-self-link': { - description: 'Ensure single resource object responses include a `self` link in a `links` object', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$.paths.*.*.responses.*.content['application/vnd.api+json'].schema.properties.data.items.properties.links.properties", - then: { - field: 'self', - function: truthy - } - }, - - /** - * Ensures that relationship objects within each resource in array responses has a `related` link - */ - 'fetching-data-fetching-resources-array-relationship-level-related-link': { - description: 'Ensure relationship objects in each resource in array resposnes include a `related` link', - message: `{{path}} - {{description}}`, - severity: 'error', - given: "$.paths.*.*.responses.*.content['application/vnd.api+json'].schema.properties.data.items.properties.relationships.properties.*.properties", - then: { - field: 'related', - function: truthy - } - } - - } -}; diff --git a/rules/jsonapi-fetching-data-ruleset.yaml b/rules/jsonapi-fetching-data-ruleset.yaml deleted file mode 100644 index 8704164..0000000 --- a/rules/jsonapi-fetching-data-ruleset.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Fetching Data -# https://jsonapi.org/format/1.0/#fetching - -# *-ruleset.yaml files generally SHOULD NOT contain any testable rules. -# all rules in this file MUST have corresponding tests. - -extends: - - jsonapi-fetching-data-fetching-resources.js \ No newline at end of file diff --git a/rules/jsonapi-query-parameters.js.old b/rules/jsonapi-query-parameters.js.old deleted file mode 100644 index cca923b..0000000 --- a/rules/jsonapi-query-parameters.js.old +++ /dev/null @@ -1,89 +0,0 @@ -// Document Structure - Links - https://jsonapi.org/format/1.0/#query-parameters -// All rules in this file MUST have corresponding tests - -import { pattern } from '@stoplight/spectral-functions'; -import { DiagnosticSeverity } from '@stoplight/types'; - -export default { - documentationUrl: 'https://jsonapi.org/format/1.0/#query-parameters', - rules: { - 'get-filter-query-parameters': { - description: 'Implementation specific query parameters MUST adhere to the same constraints as member names ' + - 'with the additional requirement that they MUST contain at least one non a-z character, which ' + - 'is selected to be [-_A-Z].', - message: '{{path}} - {{description}}', - severity: DiagnosticSeverity.Error, - given: [ - '$.paths[*][get].parameters.name', - '$.paths[*][get].parameters[*].name' - ], - then: { - field: '@key', // The value can also be @key to apply the rule to the keys of an object. - function: pattern, // I want to apply ALL Matches listed below to ALL Members - functionOptions: { - match: '[A-Z-_]' // 4 regex may have to be expanded to 4 rules - } - } - }, - - // documentationUrl: 'https://jsonapi.org/format/1.0/#document-member-names', - 'member-names-begins_with': { - description: 'Implementation specific query parameters MUST adhere to the same constraints as member names along with additional requirements.', - message: '{{path}} - {{description}}', - severity: DiagnosticSeverity.Error, - // query may be more like a POST https://dev.wix.com/api/rest/members/members/query-members - // given: "$.paths[*][get]", // "$..properties[?(@property === 'query')]", - given: [ - '$.paths[*][get].parameters.name', - '$.paths[*][get].parameters[*].name' - ], - then: { - // field: "@key", //The value can also be @key to apply the rule to the keys of an object. - function: pattern, // I want to apply ALL Matches listed below to ALL Members - functionOptions: { - match: '^[a-zA-Z0-9]' - } - - } - }, - - // documentationUrl: 'https://jsonapi.org/format/1.0/#document-member-names', - 'member-names-end_with': { - description: 'Implementation specific query parameters MUST adhere to the same constraints as member names along with additional requirements.', - message: '{{path}} - {{description}}', - severity: DiagnosticSeverity.Error, - given: [ - '$.paths[*][get].parameters.name', - '$.paths[*][get].parameters[*].name' - ], - then: { - // field: "@key", // The value can also be @key to apply the rule to the keys of an object. - function: pattern, // Want to apply ALL Matches listed below to ALL Members - functionOptions: { - match: '[a-zA-Z0-9]$' - } - } - }, - // documentationUrl: 'https://jsonapi.org/format/1.0/#document-member-names', - 'member-names-chars': { - description: 'Implementation specific query parameters MUST adhere to the same constraints as member names along with additional requirements.', - message: '{{path}} - {{description}}', - severity: DiagnosticSeverity.Error, - given: [ - '$.paths[*][get].parameters.name', - '$.paths[*][get].parameters[*].name' - ], - then: { - // field: "@key", // The value can also be @key to apply the rule to the keys of an object. - function: pattern, // Want to apply ALL Matches listed below to ALL Members - functionOptions: { - match: '[a-zA-Z0-9-_]' - } - - - } - } - - } - -}; diff --git a/rules/jsonapi-ruleset.yaml b/rules/jsonapi-ruleset.yaml deleted file mode 100644 index 45ec4bd..0000000 --- a/rules/jsonapi-ruleset.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Main JSON:API Spectral RuleSet -# https://jsonapi.org/format/1.0/ - -# *-ruleset.yaml files SHOULD NOT contain any testable items. -extends: - - jsonapi-content-negotiation-ruleset.yaml - - jsonapi-document-structure-ruleset.yaml - - jsonapi-errors-ruleset.yaml - - jsonapi-fetching-data-ruleset.yaml diff --git a/test/.eslintrc.yml b/test/.eslintrc.yml deleted file mode 100644 index 1003641..0000000 --- a/test/.eslintrc.yml +++ /dev/null @@ -1,20 +0,0 @@ -env: - mocha: true -globals: - AggregateError: 'readonly' -plugins: - - mocha -extends: - - plugin:mocha/recommended -rules: - func-names: 'off' - spaced-comment: - - error - - always - max-statements: off - no-undef: off - no-invalid-this: off - no-console: off - no-process-env: off - # Setting this to off since this is triggered due to using Chai's expect syntax, due the expression having no effect. - no-unused-expressions: off diff --git a/test/assets/example-jsonapi-oas-resolved.json b/test/assets/example-jsonapi-oas-resolved.json deleted file mode 100644 index 1d67dc6..0000000 --- a/test/assets/example-jsonapi-oas-resolved.json +++ /dev/null @@ -1,4836 +0,0 @@ -{ - "openapi": "3.0.3", - "info": { - "title": "Sample JSON:API OAS File", - "description": "Example file on how a JSON:API compliant API can be described in OAS v3+", - "version": "1.0.0", - "contact": { - "name": "Jeff Marquez", - "email": "some_email@domain.com", - "url": "http://www.example.com" - } - }, - "tags": [ - { - "name": "collection", - "description": "tag description" - }, - { - "name": "single", - "description": "tag description" - } - ], - "servers": [ - { - "url": "https://api.domain.com/v1", - "description": "production" - }, - { - "url": "https://api-sandbox.domain.com/v1", - "description": "production sandbox" - }, - { - "url": "https://api.{environment}.domain.com/v1", - "description": "pre-production", - "variables": { - "environment": { - "enum": [ - "dev", - "qa" - ], - "default": "dev" - } - } - } - ], - "paths": { - "/myResources": { - "get": { - "tags": [ - "collection" - ], - "summary": "Short Description", - "description": "A longer MEANINGFUL description. Do not copy summary.", - "security": [ - { - "ApiKeyAuth": [], - "AuthCode": [ - "actions:read" - ] - } - ], - "parameters": [ - { - "name": "filter", - "description": "schema for 'filter' query parameter", - "in": "query", - "schema": { - "type": "object" - }, - "style": "deepObject", - "example": { - "attribute": "value", - "attribute_2": "value1,value2", - "relationship.attribute": "value" - } - } - ], - "responses": { - "200": { - "description": "Successful Operation", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "https://api.domain.com/v1/myResources" - } - ] - } - } - }, - "data": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "attributes", - "relationships" - ], - "properties": { - "type": { - "enum": [ - "resources" - ] - }, - "attributes": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "example": "do-hickey" - }, - "description": { - "type": "string", - "example": "thing that does stuff" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "manufacturer": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "required": [ - "self", - "related" - ], - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/myResources/{id}/relationships/manufacturers" - } - ] - }, - "related": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/manufacturers/{id}" - } - ] - } - } - }, - "data": { - "type": "object", - "required": ["id", "type"], - "properties": { - "id":{ - "type":"string", - "pattern":"^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example":"2357c52f-6c78-4747-8106-e185c08143aa" - }, - "type":{ - "type":"string", - "enum":["manufacturers"] - }, - "meta": { - "type": "object" - } - } - } - } - } - } - } - } - } - ] - } - } - } - } - } - } - }, - "401": { - "description": "Unauthorized: Invalid or Expired Authentication", - "headers": { - "WWWAuthenticate": { - "description": "Authentication Challenge Information", - "schema": { - "type": "string", - "example": "Bearer realm=domain.com" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Unauthorized: Invalid or Expired Authentication", - "properties": { - "status": { - "type": "string", - "enum": [ - "401" - ] - }, - "title": { - "type": "string", - "enum": [ - "Unauthorized" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "401", - "title": "Unauthorized" - } - ] - } - } - } - }, - "403": { - "description": "Forbidden: Request does not have necessary permissions", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Forbidden: Request does not have necessary permissions", - "properties": { - "status": { - "type": "string", - "enum": [ - "403" - ] - }, - "title": { - "type": "string", - "enum": [ - "Forbidden" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "403", - "title": "Forbidden" - } - ] - } - } - } - }, - "406": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "415": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "default": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - } - } - }, - "post": { - "tags": [ - "single" - ], - "summary": "Create Resource", - "description": "A longer MEANINGFUL description. Do not copy summary.", - "security": [ - { - "ApiKeyAuth": [], - "AuthCode": [ - "actions:write" - ] - } - ], - "requestBody": { - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "resources" - ] - }, - "attributes": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "example": "do-hickey" - }, - "description": { - "type": "string", - "example": "thing that does stuff" - } - } - }, - "relationships": { - "type": "object", - "required": [ - "manufacturer" - ], - "properties": { - "manufacturer": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "2357c52f-6c78-4747-8106-e185c08143aa" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "properties": { - "type": { - "enum": [ - "manufacturers" - ] - } - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }, - "responses": { - "201": { - "description": "Successful Operation", - "headers": { - "Location": { - "description": "Location of the resource in question", - "schema": { - "type": "string", - "example": "http://api.domain.com/v1/{resource-colleciton-name}/{id}" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "https://api.domain.com/v1/myResources/{id}" - } - ] - } - } - }, - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "attributes", - "relationships" - ], - "properties": { - "type": { - "enum": [ - "resources" - ] - }, - "attributes": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "example": "do-hickey" - }, - "description": { - "type": "string", - "example": "thing that does stuff" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "manufacturer": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "required": [ - "self", - "related" - ], - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/myResources/{id}/relationships/manufacturers" - } - ] - }, - "related": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/manufacturers/{id}" - } - ] - } - } - }, - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "2357c52f-6c78-4747-8106-e185c08143aa" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "properties": { - "type": { - "enum": [ - "manufacturers" - ] - } - } - } - ] - } - } - } - } - } - } - } - ] - } - } - } - } - } - }, - "401": { - "description": "Unauthorized: Invalid or Expired Authentication", - "headers": { - "WWWAuthenticate": { - "description": "Authentication Challenge Information", - "schema": { - "type": "string", - "example": "Bearer realm=domain.com" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Unauthorized: Invalid or Expired Authentication", - "properties": { - "status": { - "type": "string", - "enum": [ - "401" - ] - }, - "title": { - "type": "string", - "enum": [ - "Unauthorized" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "401", - "title": "Unauthorized" - } - ] - } - } - } - }, - "403": { - "description": "Forbidden: Request does not have necessary permissions", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Forbidden: Request does not have necessary permissions", - "properties": { - "status": { - "type": "string", - "enum": [ - "403" - ] - }, - "title": { - "type": "string", - "enum": [ - "Forbidden" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "403", - "title": "Forbidden" - } - ] - } - } - } - }, - "406": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "415": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "default": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/myResources/{id}": { - "get": { - "tags": [ - "single" - ], - "summary": "Short Description", - "description": "A longer MEANINGFUL description. Do not copy summary.", - "security": [ - { - "ApiKeyAuth": [], - "AuthCode": [ - "actions:read" - ] - } - ], - "parameters": [ - { - "name": "id", - "description": "resource reference id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - } - }, - { - "name": "fields", - "description": "schema for 'fields' query parameter", - "in": "query", - "schema": { - "type": "object" - }, - "style": "deepObject", - "example": { - "resourceType": "fieldName", - "resourceType2": "filedName1,fieldName2" - } - } - ], - "responses": { - "200": { - "description": "Successful Operation", - "headers": { - "Location": { - "description": "Location of the resource in question", - "schema": { - "type": "string", - "example": "http://api.domain.com/v1/{resource-colleciton-name}/{id}" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "https://api.domain.com/v1/myResources/{id}" - } - ] - } - } - }, - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "attributes", - "relationships" - ], - "properties": { - "type": { - "enum": [ - "resources" - ] - }, - "attributes": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "example": "do-hickey" - }, - "description": { - "type": "string", - "example": "thing that does stuff" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "manufacturer": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "required": [ - "self", - "related" - ], - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/myResources/{id}/relationships/manufacturers" - } - ] - }, - "related": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/manufacturers/{id}" - } - ] - } - } - }, - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "2357c52f-6c78-4747-8106-e185c08143aa" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "properties": { - "type": { - "enum": [ - "manufacturers" - ] - } - } - } - ] - } - } - } - } - } - } - } - ] - } - } - } - } - } - }, - "401": { - "description": "Unauthorized: Invalid or Expired Authentication", - "headers": { - "WWWAuthenticate": { - "description": "Authentication Challenge Information", - "schema": { - "type": "string", - "example": "Bearer realm=domain.com" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Unauthorized: Invalid or Expired Authentication", - "properties": { - "status": { - "type": "string", - "enum": [ - "401" - ] - }, - "title": { - "type": "string", - "enum": [ - "Unauthorized" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "401", - "title": "Unauthorized" - } - ] - } - } - } - }, - "403": { - "description": "Forbidden: Request does not have necessary permissions", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Forbidden: Request does not have necessary permissions", - "properties": { - "status": { - "type": "string", - "enum": [ - "403" - ] - }, - "title": { - "type": "string", - "enum": [ - "Forbidden" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "403", - "title": "Forbidden" - } - ] - } - } - } - }, - "406": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "415": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "default": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - } - } - }, - "patch": { - "tags": [ - "single" - ], - "summary": "Short Description", - "description": "A longer MEANINGFUL description. Do not copy summary.", - "security": [ - { - "ApiKeyAuth": [], - "AuthCode": [ - "actions:write" - ] - } - ], - "parameters": [ - { - "name": "id", - "description": "resource reference id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "attributes" - ], - "properties": { - "type": { - "enum": [ - "resources" - ] - }, - "attributes": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "example": "do-hickey" - }, - "description": { - "type": "string", - "example": "thing that does stuff", - "nullable": true - } - } - }, - "relationships": { - "type": "object", - "required": [ - "manufacturer" - ], - "properties": { - "manufacturer": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "2357c52f-6c78-4747-8106-e185c08143aa" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "properties": { - "type": { - "enum": [ - "manufacturers" - ] - } - } - } - ], - "nullable": true - } - } - } - } - } - } - } - ] - } - } - } - } - } - }, - "responses": { - "200": { - "description": "Successful Operation", - "headers": { - "Location": { - "description": "Location of the resource in question", - "schema": { - "type": "string", - "example": "http://api.domain.com/v1/{resource-colleciton-name}/{id}" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "https://api.domain.com/v1/myResources/{id}" - } - ] - } - } - }, - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "attributes", - "relationships" - ], - "properties": { - "type": { - "enum": [ - "resources" - ] - }, - "attributes": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "example": "do-hickey" - }, - "description": { - "type": "string", - "example": "thing that does stuff" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "manufacturer": { - "type": "object", - "required": [ - "links", - "data" - ], - "properties": { - "links": { - "type": "object", - "required": [ - "self", - "related" - ], - "properties": { - "self": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/myResources/{id}/relationships/manufacturers" - } - ] - }, - "related": { - "allOf": [ - { - "type": "string" - }, - { - "example": "http://api.domain.com/v1/manufacturers/{id}" - } - ] - } - } - }, - "data": { - "allOf": [ - { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "2357c52f-6c78-4747-8106-e185c08143aa" - }, - "type": { - "type": "string" - } - } - }, - { - "type": "object", - "properties": { - "type": { - "enum": [ - "manufacturers" - ] - } - } - } - ] - } - } - } - } - } - } - } - ] - } - } - } - } - } - }, - "401": { - "description": "Unauthorized: Invalid or Expired Authentication", - "headers": { - "WWWAuthenticate": { - "description": "Authentication Challenge Information", - "schema": { - "type": "string", - "example": "Bearer realm=domain.com" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Unauthorized: Invalid or Expired Authentication", - "properties": { - "status": { - "type": "string", - "enum": [ - "401" - ] - }, - "title": { - "type": "string", - "enum": [ - "Unauthorized" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "401", - "title": "Unauthorized" - } - ] - } - } - } - }, - "403": { - "description": "Forbidden: Request does not have necessary permissions", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Forbidden: Request does not have necessary permissions", - "properties": { - "status": { - "type": "string", - "enum": [ - "403" - ] - }, - "title": { - "type": "string", - "enum": [ - "Forbidden" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "403", - "title": "Forbidden" - } - ] - } - } - } - }, - "406": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "415": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "default": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "single" - ], - "summary": "Short Description", - "description": "A longer MEANINGFUL description. Do not copy summary.", - "security": [ - { - "ApiKeyAuth": [], - "AuthCode": [ - "actions:delete" - ] - } - ], - "parameters": [ - { - "name": "id", - "description": "resource reference id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$", - "example": "4257c52f-6c78-4747-8106-e185c081436b" - } - } - ], - "responses": { - "204": { - "description": "Successful Operation. No Content." - }, - "401": { - "description": "Unauthorized: Invalid or Expired Authentication", - "headers": { - "WWWAuthenticate": { - "description": "Authentication Challenge Information", - "schema": { - "type": "string", - "example": "Bearer realm=domain.com" - } - } - }, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Unauthorized: Invalid or Expired Authentication", - "properties": { - "status": { - "type": "string", - "enum": [ - "401" - ] - }, - "title": { - "type": "string", - "enum": [ - "Unauthorized" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "401", - "title": "Unauthorized" - } - ] - } - } - } - }, - "403": { - "description": "Forbidden: Request does not have necessary permissions", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "allOf": [ - { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - }, - { - "type": "object", - "description": "Forbidden: Request does not have necessary permissions", - "properties": { - "status": { - "type": "string", - "enum": [ - "403" - ] - }, - "title": { - "type": "string", - "enum": [ - "Forbidden" - ] - } - } - } - ] - } - } - } - }, - "example": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "403", - "title": "Forbidden" - } - ] - } - } - } - }, - "406": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "415": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - }, - "default": { - "description": "Error", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "description": "JSON:API Error Object", - "properties": { - "id": { - "type": "string", - "description": "a unique identifier for this particular occurrence of the problem" - }, - "links": { - "type": "object", - "description": "links that lead to further detail about the particular occurrence of the problem", - "properties": { - "about": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "href" - ], - "properties": { - "href": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - ] - } - } - }, - "status": { - "type": "string", - "description": "the HTTP status code applicable to this problem" - }, - "code": { - "type": "string", - "description": "an application-specific error code" - }, - "title": { - "type": "string", - "description": "a human-readable summary specific of the problem. Usually the http status friendly name." - }, - "detail": { - "type": "string", - "description": "a human-readable explanation specific to this occurrence of the problem" - }, - "source": { - "type": "object", - "description": "an object containing references to the source of the error", - "properties": { - "pointer": { - "description": "a JSON Pointer [RFC6901] to the associated entity in the request document", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "parameter": { - "description": "a string indicating which URI query parameter caused the error", - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - } - } - }, - "examples": { - "400 - Bad Request": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - } - ] - } - }, - "404 - Not Found": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "404", - "title": "Not Found" - } - ] - } - }, - "500 - Server Error": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "500", - "title": "Internal Server Error" - } - ] - } - }, - "Multiple Errors": { - "value": { - "errors": [ - { - "id": "e50d3928-c1f0-4e10-888b-b110734656ab", - "status": "400", - "title": "Bad Request", - "source": { - "parameter": "id" - } - }, - { - "id": "b6ad7d24-4dec-4ba0-931c-52731a9469e3", - "status": "400", - "title": "Bad Request", - "source": { - "pointer": "/data/attributes/name" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "securitySchemes": { - "ApiKeyAuth": { - "type": "apiKey", - "description": "Api Key value. First level of client identification and access control to proxy/gateway", - "in": "header", - "name": "api-key" - }, - "AuthCode": { - "type": "oauth2", - "flows": { - "authorizationCode": { - "authorizationUrl": "https://api.domain.com/oauth/authorize", - "tokenUrl": "https://api.domain.com/oauth/token", - "refreshUrl": "https://api.domain.com/oauth/refresh", - "scopes": { - "actions:write": "modify actions the end-user has access to", - "actions:read": "read actions the end-user has access to", - "actions:delete": "delete actions the end-user has access to" - } - } - } - } - } - } -} diff --git a/test/assets/jsonapi-schema.yaml b/test/assets/jsonapi-schema.yaml deleted file mode 100644 index d85f7f1..0000000 --- a/test/assets/jsonapi-schema.yaml +++ /dev/null @@ -1,287 +0,0 @@ -"$schema": http://json-schema.org/draft-06/schema# -title: JSON:API Schema -description: This is a schema for responses in the JSON:API format. For more, see - http://jsonapi.org -oneOf: -- "$ref": "#/definitions/success" -- "$ref": "#/definitions/failure" -- "$ref": "#/definitions/info" -definitions: - success: - type: object - required: - - data - properties: - data: - "$ref": "#/definitions/data" - included: - description: To reduce the number of HTTP requests, servers **MAY** allow - responses that include related resources along with the requested primary - resources. Such responses are called "compound documents". - type: array - items: - "$ref": "#/definitions/resource" - uniqueItems: true - meta: - "$ref": "#/definitions/meta" - links: - description: Link members related to the primary data. - allOf: - - "$ref": "#/definitions/links" - - "$ref": "#/definitions/pagination" - jsonapi: - "$ref": "#/definitions/jsonapi" - additionalProperties: false - failure: - type: object - required: - - errors - properties: - errors: - type: array - items: - "$ref": "#/definitions/error" - uniqueItems: true - meta: - "$ref": "#/definitions/meta" - jsonapi: - "$ref": "#/definitions/jsonapi" - links: - "$ref": "#/definitions/links" - additionalProperties: false - info: - type: object - required: - - meta - properties: - meta: - "$ref": "#/definitions/meta" - links: - "$ref": "#/definitions/links" - jsonapi: - "$ref": "#/definitions/jsonapi" - additionalProperties: false - meta: - description: Non-standard meta-information that can not be represented as an attribute - or relationship. - type: object - additionalProperties: true - data: - description: The document's "primary data" is a representation of the resource - or collection of resources targeted by a request. - oneOf: - - "$ref": "#/definitions/resource" - - description: An array of resource objects, an array of resource identifier objects, - or an empty array ([]), for requests that target resource collections. - type: array - items: - "$ref": "#/definitions/resource" - uniqueItems: true - - description: null if the request is one that might correspond to a single resource, - but doesn't currently. - type: 'null' - resource: - description: '"Resource objects" appear in a JSON:API document to represent resources.' - type: object - required: - - type - - id - properties: - type: - type: string - id: - type: string - attributes: - "$ref": "#/definitions/attributes" - relationships: - "$ref": "#/definitions/relationships" - links: - "$ref": "#/definitions/links" - meta: - "$ref": "#/definitions/meta" - additionalProperties: false - relationshipLinks: - description: A resource object **MAY** contain references to other resource objects - ("relationships"). Relationships may be to-one or to-many. Relationships can - be specified by including a member in a resource's links object. - type: object - properties: - self: - description: A `self` member, whose value is a URL for the relationship itself - (a "relationship URL"). This URL allows the client to directly manipulate - the relationship. For example, it would allow a client to remove an `author` - from an `article` without deleting the people resource itself. - "$ref": "#/definitions/link" - related: - "$ref": "#/definitions/link" - additionalProperties: true - links: - type: object - additionalProperties: - "$ref": "#/definitions/link" - link: - description: 'A link **MUST** be represented as either: a string containing the - link''s URL or a link object.' - oneOf: - - description: A string containing the link's URL. - type: string - format: uri-reference - - type: object - required: - - href - properties: - href: - description: A string containing the link's URL. - type: string - format: uri-reference - meta: - "$ref": "#/definitions/meta" - attributes: - description: Members of the attributes object ("attributes") represent information - about the resource object in which it's defined. - type: object - patternProperties: - "^[a-zA-Z0-9](?:[-\\w]*[a-zA-Z0-9])?$": - description: Attributes may contain any valid JSON value. - not: - anyOf: - - required: - - relationships - - required: - - links - - required: - - id - - required: - - type - additionalProperties: false - relationships: - description: Members of the relationships object ("relationships") represent references - from the resource object in which it's defined to other resource objects. - type: object - patternProperties: - "^[a-zA-Z0-9](?:[-\\w]*[a-zA-Z0-9])?$": - properties: - links: - "$ref": "#/definitions/relationshipLinks" - data: - description: Member, whose value represents "resource linkage". - oneOf: - - "$ref": "#/definitions/relationshipToOne" - - "$ref": "#/definitions/relationshipToMany" - meta: - "$ref": "#/definitions/meta" - anyOf: - - required: - - data - - required: - - meta - - required: - - links - not: - anyOf: - - required: - - id - - required: - - type - additionalProperties: false - additionalProperties: false - relationshipToOne: - description: References to other resource objects in a to-one ("relationship"). - Relationships can be specified by including a member in a resource's links object. - anyOf: - - "$ref": "#/definitions/empty" - - "$ref": "#/definitions/linkage" - relationshipToMany: - description: An array of objects each containing "type" and "id" members for to-many - relationships. - type: array - items: - "$ref": "#/definitions/linkage" - uniqueItems: true - empty: - description: Describes an empty to-one relationship. - type: 'null' - linkage: - description: The "type" and "id" to non-empty members. - type: object - required: - - type - - id - properties: - type: - type: string - id: - type: string - meta: - "$ref": "#/definitions/meta" - additionalProperties: false - pagination: - type: object - properties: - first: - description: The first page of data - oneOf: - - "$ref": "#/definitions/link" - - type: 'null' - last: - description: The last page of data - oneOf: - - "$ref": "#/definitions/link" - - type: 'null' - prev: - description: The previous page of data - oneOf: - - "$ref": "#/definitions/link" - - type: 'null' - next: - description: The next page of data - oneOf: - - "$ref": "#/definitions/link" - - type: 'null' - jsonapi: - description: An object describing the server's implementation - type: object - properties: - version: - type: string - meta: - "$ref": "#/definitions/meta" - additionalProperties: false - error: - type: object - properties: - id: - description: A unique identifier for this particular occurrence of the problem. - type: string - links: - "$ref": "#/definitions/links" - status: - description: The HTTP status code applicable to this problem, expressed as - a string value. - type: string - code: - description: An application-specific error code, expressed as a string value. - type: string - title: - description: A short, human-readable summary of the problem. It **SHOULD NOT** - change from occurrence to occurrence of the problem, except for purposes - of localization. - type: string - detail: - description: A human-readable explanation specific to this occurrence of the - problem. - type: string - source: - type: object - properties: - pointer: - description: A JSON Pointer [RFC6901] to the associated entity in the - request document [e.g. "/data" for a primary data object, or "/data/attributes/title" - for a specific attribute]. - type: string - parameter: - description: A string indicating which query parameter caused the error. - type: string - meta: - "$ref": "#/definitions/meta" - additionalProperties: false diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayAttributesType.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayAttributesType.js deleted file mode 100644 index 98f9446..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayAttributesType.js +++ /dev/null @@ -1,818 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayAttributesType = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - // Changing `attributes` type to generate a failing scenario - original: "object" - "type": "fail", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayAttributesType; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoForeignKeys.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoForeignKeys.js deleted file mode 100644 index 0a1287f..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoForeignKeys.js +++ /dev/null @@ -1,839 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayNoForeignKeys = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "foreignKey_id": { - "type": "string" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayNoForeignKeys; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoLinksMember.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoLinksMember.js deleted file mode 100644 index bdd1cde..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoLinksMember.js +++ /dev/null @@ -1,840 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayNoLinksMember = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - // Adding this `links` member to generate a failing scenario - "links": { - "type": "object" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayNoLinksMember; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoRelationshipsMember.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoRelationshipsMember.js deleted file mode 100644 index 432442d..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoRelationshipsMember.js +++ /dev/null @@ -1,840 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayNoRelationshipsMember = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - // Adding this `relationships` member to generate a failing scenario - "relationships": { - "type": "object" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayNoRelationshipsMember; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoForeignKeys.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoForeignKeys.js deleted file mode 100644 index 8d4943f..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoForeignKeys.js +++ /dev/null @@ -1,840 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleNoForeignKeys = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - // Creating foreign key to generate a failing scenario - "foreignKey_id": { - "type": "string" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleNoForeignKeys; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoLinksMember.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoLinksMember.js deleted file mode 100644 index 09956ed..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoLinksMember.js +++ /dev/null @@ -1,840 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleNoLinksMember = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - // Adding this `links` member to generate a failing scenario - "links": { - "type": "object" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleNoLinksMember; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoRelationshipsMember.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoRelationshipsMember.js deleted file mode 100644 index 823d691..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoRelationshipsMember.js +++ /dev/null @@ -1,840 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleNoRelationshipsMember = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - // Adding this `relationships` member to generate a failing scenario - "relationships": { - "type": "object" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleNoRelationshipsMember; diff --git a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleType.js b/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleType.js deleted file mode 100644 index 60acbaa..0000000 --- a/test/docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleType.js +++ /dev/null @@ -1,837 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-443", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-333", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "401": { - "description": "Unauthorized - Authentication credentials were missing or invalid.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "unauthorizedError": { - "summary": "Example of a 401 Unauthorized error", - "value": { - "errors": [ - { - "id": "error-223", - "status": "401", - "title": "Unauthorized", - "detail": "Authentication credentials were not provided or are invalid.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/401" - } - } - ] - } - } - } - } - } - }, - "403": { - "description": "Forbidden - The request was valid, but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "forbiddenError": { - "summary": "Example of a 403 Forbidden error", - "value": { - "errors": [ - { - "id": "error-543", - "status": "403", - "title": "Unauthorized", - "detail": "You do not have permission to perform this aciton.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/403" - } - } - ] - } - } - } - } - } - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - // Changing to generate a failing scenario - original: 'object' - "type": "fail", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleType; diff --git a/test/docs/documentStructure/resourceObjects/fields/invalidApiDocumentNoTypeOrId.js b/test/docs/documentStructure/resourceObjects/fields/invalidApiDocumentNoTypeOrId.js deleted file mode 100644 index 8198cd0..0000000 --- a/test/docs/documentStructure/resourceObjects/fields/invalidApiDocumentNoTypeOrId.js +++ /dev/null @@ -1,848 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentNoTypeOrId = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - // Inserting a `id` field to generate a failing scenario for rule `document-structure-resource-fields-no-type-or-id` - "id": { - "type": "string" - }, - // Inserting a `type` field to generate a failing scenario for rule `document-structure-resource-fields-no-type-or-id` - "type": { - "type": "string" - }, - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - // Inserting a `id` field to generate a failing scenario for rule `document-structure-resource-fields-no-type-or-id` - "id": { - "type": "string" - }, - // Inserting a `type` field to generate a failing scenario for rule `document-structure-resource-fields-no-type-or-id` - "type": { - "type": "string" - }, - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentNoTypeOrId; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdMember.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdMember.js deleted file mode 100644 index d501a9d..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdMember.js +++ /dev/null @@ -1,834 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayIdMember = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - // Removing the `id` member to generate a failing scenario for rule `document-structure-resource-array-identification-id-member` - // "id": { - // "type": "string", - // "description": "Unique identifier for the user" - // }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - // Removing `id` member to generate a failing scenario for rule `document-structure-resource-array-identification-id-member` - // "id": { - // "type": "string" - // }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayIdMember; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdType.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdType.js deleted file mode 100644 index 2d0ec6d..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdType.js +++ /dev/null @@ -1,834 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayIdType = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - // Changing the `id` member type to generate a failing scenario for rule `document-structure-resource-array-identification-id-type` - "type": "fail", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - // Changing the `id` member type to generate a failing scenario for rule `document-structure-resource-array-identification-id-type` - "type": "fail" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayIdType; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeMember.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeMember.js deleted file mode 100644 index 86356b0..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeMember.js +++ /dev/null @@ -1,835 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayTypeMember = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - // Removing `type` member to generate a failing scenario for rule `document-structure-resource-array-identification-type-member` - // "type": { - // "type": "string", - // "description": "Type of the resource (users)" - // }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - // Removing `type` member to generate a failing scenario for rule `document-structure-resource-array-identification-type-member` - // "type": { - // "type": "string" - // }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - // Removing `type` member to generate a failing scenario for rule `document-structure-resource-array-identification-type-member` - // "type": { - // "type": "string" - // }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayTypeMember; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeType.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeType.js deleted file mode 100644 index 708abc5..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeType.js +++ /dev/null @@ -1,835 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayTypeType = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - // changing `type` member type from 'string' to 'fail to generate a failing scenario for rule `document-structure-resource-array-identification-type-type` - "type": "fail", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - // changing `type` member type from 'string' to 'fail to generate a failing scenario for rule `document-structure-resource-array-identification-type-type` - "type": "fail" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - // changing `type` member type from 'string' to 'fail to generate a failing scenario for rule `document-structure-resource-array-identification-type-type` - "type": "fail" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayTypeType; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdMember.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdMember.js deleted file mode 100644 index a01a6f3..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdMember.js +++ /dev/null @@ -1,834 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleIdMember = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - // Removing the `id` member to generate a failing scenario for rule `document-structure-resource-single-identification-id-member` - // "id": { - // "type": "string", - // "description": "Unique identifier for the user" - // }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - // Removing `id` member to generate a failing scenario for rule `document-structure-resource-single-identification-id-member` - // "id": { - // "type": "string" - // }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleIdMember; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdType.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdType.js deleted file mode 100644 index ff4804e..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdType.js +++ /dev/null @@ -1,834 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleIdType = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - // Changing the `id` member type to generate a failing scenario for rule `document-structure-resource-single-identification-id-type` - "type": "fail", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - // Changing the `id` member type to generate a failing scenario for rule `document-structure-resource-single-identification-id-type` - "type": "fail" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleIdType; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeMember.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeMember.js deleted file mode 100644 index cfba41e..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeMember.js +++ /dev/null @@ -1,835 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleTypeMember = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - // Removing `type` member to generate a failing scenario for rule `document-structure-resource-single-identification-type-member` - // "type": { - // "type": "string", - // "description": "Type of the resource (users)" - // }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - // Removing `type` member to generate a failing scenario for rule `document-structure-resource-single-identification-type-member` - // "type": { - // "type": "string" - // }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - // Removing `type` member to generate a failing scenario for rule `document-structure-resource-single-identification-type-member` - // "type": { - // "type": "string" - // }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleTypeMember; diff --git a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeType.js b/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeType.js deleted file mode 100644 index 722f468..0000000 --- a/test/docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeType.js +++ /dev/null @@ -1,835 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleTypeType = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - // changing `type` member type from 'string' to 'fail to generate a failing scenario for rule `document-structure-resource-single-identification-type-type` - "type": "fail", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - // changing `type` member type from 'string' to 'fail to generate a failing scenario for rule `document-structure-resource-single-identification-type-type` - "type": "fail" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - // changing `type` member type from 'string' to 'fail to generate a failing scenario for rule `document-structure-resource-single-identification-type-type` - "type": "fail" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleTypeType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayAttributesType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayAttributesType.js deleted file mode 100644 index ad84800..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayAttributesType.js +++ /dev/null @@ -1,671 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayAttributesType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - // Original: "object" - creating failing scenario - "type": "string", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayAttributesType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdRequired.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdRequired.js deleted file mode 100644 index 358e8b6..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdRequired.js +++ /dev/null @@ -1,671 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayIdRequired = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - // Creating a failing scenario where `id` member is required. removing will cause the rule to fail - // "id": { - // "type": "string", - // "description": "Unique identifier for the user" - // }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayIdRequired; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdType.js deleted file mode 100644 index e24c418..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdType.js +++ /dev/null @@ -1,671 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayIdType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - // Original: "string" - creating failing scenario - "type": "object", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayIdType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructure.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructure.js deleted file mode 100644 index 9cead0a..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructure.js +++ /dev/null @@ -1,675 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayStructure = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - // Failing scenario, not following proper array structure - "idd": { - "type": "string", - "description": "Unique identifier for the user" - }, - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayStructure; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructureLength.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructureLength.js deleted file mode 100644 index 4879051..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructureLength.js +++ /dev/null @@ -1,680 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayStructureLength = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - }, - // Creating a failing scenario that exceeds to maximum amount of members allowed for a `Resource Object` - "fiveMember": { - "type": "string" - }, - "sixMember": { - "type": "string" - }, - "sevenMember": { - "type": "string" - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayStructureLength; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeRequired.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeRequired.js deleted file mode 100644 index 16c8572..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeRequired.js +++ /dev/null @@ -1,671 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayTypeRequired = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - // Creating a failing scenario where `type` member is required. removing will cause the rule to fail - // "type": { - // "type": "string", - // "description": "Type of the resource (users)" - // }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayTypeRequired; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeType.js deleted file mode 100644 index 0a27443..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeType.js +++ /dev/null @@ -1,671 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayTypeType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - // Original: "string" - creating failing scenario - "type": "object", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayTypeType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleAttributesType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleAttributesType.js deleted file mode 100644 index fe0ed17..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleAttributesType.js +++ /dev/null @@ -1,671 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleAttributesType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - // Original: "object" - "type": "string", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleAttributesType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdRequired.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdRequired.js deleted file mode 100644 index 0d7aeb1..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdRequired.js +++ /dev/null @@ -1,672 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleIdRequired = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - // Removed type, which is required. This is a failing scenario - // "id": { - // "type": "string", - // "description": "Unique identifier for the user" - // }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - // Removed type, which is required. This is a failing scenario - // "id": { - // "type": "string" - // }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleIdRequired; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdType.js deleted file mode 100644 index fcd1082..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdType.js +++ /dev/null @@ -1,672 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleIdType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - // Original: "string" - "type": "object", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - // Original: "string" - "type": "object" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleIdType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructure.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructure.js deleted file mode 100644 index e7a8ab8..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructure.js +++ /dev/null @@ -1,659 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleStructure = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "idd": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleStructure; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructureLength.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructureLength.js deleted file mode 100644 index a501d48..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructureLength.js +++ /dev/null @@ -1,694 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleStructureLength = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - }, - // The below three members are created to generated a failing rule that is existing the maximum allowed members in a `Resource Object` - "fiveMember": { - "type": "string" - }, - "sixMember": { - "type": "string" - }, - "sevenMember": { - "type": "string" - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - // The below five members are created to generated a failing rule that is existing the maximum allowed members in a `Resource Object` - "threeMember": { - "type": "string" - }, - "fourMember": { - "type": "string" - }, - "fiveMember": { - "type": "string" - }, - "sixMember": { - "type": "string" - }, - "sevenMember": { - "type": "string" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - // The below four members are created to generated a failing rule that is existing the maximum allowed members in a `Resource Object` - "fourMember": { - "type": "string" - }, - "fiveMember": { - "type": "string" - }, - "sixMember": { - "type": "string" - }, - "sevenMember": { - "type": "string" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleStructureLength; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeRequired.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeRequired.js deleted file mode 100644 index d2f7719..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeRequired.js +++ /dev/null @@ -1,673 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleTypeRequired = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - // Removed type, which is required. This is a failing scenario - // "type": { - // "type": "string", - // "description": "Type of the resource (users)" - // }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - // Removed type, which is required. This is a failing scenario - // "type": { - // "type": "string" - // }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - // Removed type, which is required. This is a failing scenario - // "type": { - // "type": "string" - // }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleTypeRequired; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeType.js deleted file mode 100644 index 211f389..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeType.js +++ /dev/null @@ -1,673 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleTypeType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - // Oriignal: "string" - "type": "object", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - // Original: "string" - "type": "object" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - // Original: "string" - "type": "object" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleTypeType; diff --git a/test/docs/documentStructure/resourceObjects/invalidApiDocumentType.js b/test/docs/documentStructure/resourceObjects/invalidApiDocumentType.js deleted file mode 100644 index 3f2dc7a..0000000 --- a/test/docs/documentStructure/resourceObjects/invalidApiDocumentType.js +++ /dev/null @@ -1,674 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentType = { - "openapi": "3.1.0", - "info": { - "title": "User Management API", - "description": "This API manages user information, conforming to JSON:API v1.0 standards.", - "version": "1.1.0" - }, - "servers": [ - { - "url": "https://api.usermanagement.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "pageSize", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": { - "id": "error-456", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be understood due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "User deleted" - }, - "401": { - "description": "Authentication credentials were missing or incorrect.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "403": { - "description": "The request was valid but the server is refusing action due to insufficient permissions.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - // original: "object" - "type": "string", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - // Original: "array" - "type": "string", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri" - }, - "last": { - "type": "string", - "format": "uri" - }, - "prev": { - "type": "string", - "format": "uri" - }, - "next": { - "type": "string", - "format": "uri" - } - } - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - // original: "object" - "type": "string", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - // original: "object" - "type": "string", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - } - } - }, - "AttributesObject": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/AttributesObject" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": ["400", "401", "403", "404", "405", "406", "409", "422", "500", "502", "503"], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentArrayStructure.js b/test/docs/errors/errorObjects/invalidApiDocumentArrayStructure.js deleted file mode 100644 index d293f98..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentArrayStructure.js +++ /dev/null @@ -1,201 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayStructure = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - - /** - * validating here - * original: array - * Fail: object - * */ - "type": "object", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - // Original: "string" - "type": "object" - }, - "idtw": { - // Original: "string" - "type": "object" - }, - "links": { - // Original: "object" - "type": "string", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - // Original: "string" - "type": "object" - }, - "code": { - // Original: "string" - "type": "object" - }, - "title": { - // Original: "string" - "type": "object" - }, - "detail": { - // Original: "string" - "type": "object" - }, - "source": { - // Original: "object" - "type": "string", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - // Original: "object" - "type": "string", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentArrayStructure; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsCodeType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsCodeType.js deleted file mode 100644 index f615e4d..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsCodeType.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsCodeType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - // Original: "string" - "type": "object" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsCodeType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsDetailType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsDetailType.js deleted file mode 100644 index e54cbf0..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsDetailType.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsDetailType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - // Orinigal: "string" - "type": "object" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsDetailType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsIdType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsIdType.js deleted file mode 100644 index 7840370..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsIdType.js +++ /dev/null @@ -1,191 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsIdType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - // Original: "string" - "type": "object" - }, - "links": { - // Original: "object" - "type": "string", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - // Original: "string" - "type": "object" - }, - "code": { - // Original: "string" - "type": "object" - }, - "title": { - // Original: "string" - "type": "object" - }, - "detail": { - // Original: "string" - "type": "object" - }, - "source": { - // Original: "object" - "type": "string", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - // Original: "object" - "type": "string", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsIdType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsLinksMembers.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsLinksMembers.js deleted file mode 100644 index 23bbc80..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsLinksMembers.js +++ /dev/null @@ -1,197 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsLinksMembers = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - - /** - * validating here - * original: array - * Fail: object - * */ - "type": "object", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - // Original: "string" - "type": "object" - }, - "links": { - // Original: "object" - "type": "object", - "properties": { - "aboutt": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - // Original: "string" - "type": "object" - }, - "code": { - // Original: "string" - "type": "object" - }, - "title": { - // Original: "string" - "type": "object" - }, - "detail": { - // Original: "string" - "type": "object" - }, - "source": { - // Original: "object" - "type": "string", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - // Original: "object" - "type": "string", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsLinksMembers; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsLinksStructureLength.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsLinksStructureLength.js deleted file mode 100644 index 953fb22..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsLinksStructureLength.js +++ /dev/null @@ -1,197 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsLinksStructureLength = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - - /** - * validating here - * original: array - * Fail: object - * */ - "type": "object", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - // Original: "string" - "type": "object" - }, - "links": { - // Original: "object" - "type": "string", - "properties": { - // "about": { - // "type": "string", - // "format": "uri" - // } - } - }, - "status": { - // Original: "string" - "type": "object" - }, - "code": { - // Original: "string" - "type": "object" - }, - "title": { - // Original: "string" - "type": "object" - }, - "detail": { - // Original: "string" - "type": "object" - }, - "source": { - // Original: "object" - "type": "string", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - // Original: "object" - "type": "string", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsLinksStructureLength; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceMembers.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceMembers.js deleted file mode 100644 index 6f4ef9f..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceMembers.js +++ /dev/null @@ -1,193 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsSourceMembers = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - // This will fail since it is spelled incorrectly - // Original: "pointer" - "pointerr": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsSourceMembers; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceParameterType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceParameterType.js deleted file mode 100644 index ac06138..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceParameterType.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsSourceParameterType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - // Original: "string" - "type": "object" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsSourceParameterType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourcePointerType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsSourcePointerType.js deleted file mode 100644 index 9cb4cad..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourcePointerType.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsSourcePointerType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - // Original: "string" - "type": "object" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsSourcePointerType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceStructureLength.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceStructureLength.js deleted file mode 100644 index 774c298..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceStructureLength.js +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsSourceStructureLength = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - // Removing all members will also fail the rule - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - }, - // Adding this member makes the rule fail - "failingMember": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsSourceStructureLength; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceType.js deleted file mode 100644 index 0a95cf9..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsSourceType.js +++ /dev/null @@ -1,184 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsSourceType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - // Original: "object" - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsSourceType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsStatusType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsStatusType.js deleted file mode 100644 index f3e298a..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsStatusType.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsStatusType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - // Original: "string" - "type": "object" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsStatusType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentItemsTitleType.js b/test/docs/errors/errorObjects/invalidApiDocumentItemsTitleType.js deleted file mode 100644 index 16e40e6..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentItemsTitleType.js +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentItemsTitleType = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - // Original: "string" - "type": "object" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentItemsTitleType; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentObjectStructure.js b/test/docs/errors/errorObjects/invalidApiDocumentObjectStructure.js deleted file mode 100644 index 6706c9f..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentObjectStructure.js +++ /dev/null @@ -1,191 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentObjectStructure = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - // Original: "id" - "idd": { - "type": "string" - }, - // Original: "links" - "linkss": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - // Original: "status" - "statuss": { - "type": "string" - }, - // Original: "code" - "codee": { - "type": "string" - }, - // Original: "title" - "titlee": { - "type": "string" - }, - // Original: "detail" - "detaill": { - "type": "string" - }, - // Original: "source" - "sourcee": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - // Original: "meta" - "metaa": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentObjectStructure; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentObjectStructureLength.js b/test/docs/errors/errorObjects/invalidApiDocumentObjectStructureLength.js deleted file mode 100644 index 80c358b..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentObjectStructureLength.js +++ /dev/null @@ -1,195 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentObjectStructureLength = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - // Original: "string" - "type": "object" - }, - "ExtraMember": { - // Original: "string" - "type": "object" - }, - "links": { - // Original: "object" - "type": "string", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - // Original: "string" - "type": "object" - }, - "code": { - // Original: "string" - "type": "object" - }, - "title": { - // Original: "string" - "type": "object" - }, - "detail": { - // Original: "string" - "type": "object" - }, - "source": { - // Original: "object" - "type": "string", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - // Original: "object" - "type": "string", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentObjectStructureLength; diff --git a/test/docs/errors/errorObjects/invalidApiDocumentProcessingErrorsGeneralCode.js b/test/docs/errors/errorObjects/invalidApiDocumentProcessingErrorsGeneralCode.js deleted file mode 100644 index cca5b52..0000000 --- a/test/docs/errors/errorObjects/invalidApiDocumentProcessingErrorsGeneralCode.js +++ /dev/null @@ -1,212 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentProcessingErrorsGeneralCode = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - // "200": { - // "description": "Successful response with user information", - // "content": { - // "application/vnd.api+json": { - // "schema": { - // "type": "object", - // "properties": { - // "data": { - // "type": "object", - // "properties": { - // "id": { - // "type": "string" - // }, - // "type": { - // "type": "string", - // "enum": [ - // "user" - // ] - // }, - // "attributes": { - // "type": "object", - // "properties": { - // "name": { - // "type": "string" - // }, - // "email": { - // "type": "string" - // } - // // Other user attributes... - // } - // } - // } - // } - // } - // }, - // "examples": { - // "user": { - // "summary": "User Example", - // "value": { - // "data": { - // "id": "12345", - // "type": "user", - // "attributes": { - // "name": "John Doe", - // "email": "john.doe@example.com" - // // Other user attributes... - // } - // } - // } - // } - // } - // } - // } - // }, - // "400": { - // "description": "Bad Request", - // "content": { - // "application/vnd.api+json": { - // "schema": { - // "$ref": "#/components/schemas/JsonApiError" - // } - // } - // } - // } - // , - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - // , - // "500": { - // "description": "Internal Server Error", - // "content": { - // "application/vnd.api+json": { - // "schema": { - // "$ref": "#/components/schemas/JsonApiError" - // } - // } - // } - // }, - // , - // "505": { - // "description": "Internal Server Error", - // "content": { - // "application/vnd.api+json": { - // "schema": { - // "$ref": "#/components/schemas/JsonApiError" - // } - // } - // } - // } - - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - }, - "type": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - }, - "header": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default invalidApiDocumentProcessingErrorsGeneralCode; diff --git a/test/docs/errors/errorObjects/validApiDocument.js b/test/docs/errors/errorObjects/validApiDocument.js deleted file mode 100644 index 1efc4ad..0000000 --- a/test/docs/errors/errorObjects/validApiDocument.js +++ /dev/null @@ -1,191 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const validApiDocument = { - "openapi": "3.1.0", - "info": { - "title": "User Information API", - "version": "1.0.0", - "description": "API for retrieving user information" - }, - "paths": { - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successful response with user information", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "user" - ] - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - // Other user attributes... - } - } - } - } - } - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - // Other user attributes... - } - } - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Test": { - "type": "object", - "properties": { - "test": { - "type": "string" - } - } - }, - "JsonApiError": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - "status": { - "type": "string" - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": [ - "detail" - ] - } - } - } -}; - -export default validApiDocument; diff --git a/test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItems.js b/test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItems.js deleted file mode 100644 index ff46f56..0000000 --- a/test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItems.js +++ /dev/null @@ -1,833 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayMaxItems = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - // the `maxItems` keyword is missing which will generating a failing scenario for rule `errors-processing-errors-array-max-items` - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayMaxItems; diff --git a/test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItemsValue.js b/test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItemsValue.js deleted file mode 100644 index d24fee5..0000000 --- a/test/docs/errors/processingErrors/invalidApiDocumentArrayMaxItemsValue.js +++ /dev/null @@ -1,834 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayMaxItemsValue = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.0" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - // The `maxItems` keyword is not providing the correct value which will generating a failing scenario for rule `errors-processing-errors-array-max-items-value` - "maxItems": 2, - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayMaxItemsValue; diff --git a/test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayLevelSelfLink.js b/test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayLevelSelfLink.js deleted file mode 100644 index f0f31c3..0000000 --- a/test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayLevelSelfLink.js +++ /dev/null @@ -1,846 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayLevelSelfLink = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.2" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "links": { - "type": "object", - "properties": { - // Removing the `self` member to generate a failing scenario for rule `fetching-data-fetching-resources-array-level-self-link` - "fail": { - "type": "string", - "format": "uri" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayLevelSelfLink; diff --git a/test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayRelationshipLevelRelatedLink.js b/test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayRelationshipLevelRelatedLink.js deleted file mode 100644 index 5f19dbd..0000000 --- a/test/docs/fetchingData/fetchingResources/invalidApiDocumentArrayRelationshipLevelRelatedLink.js +++ /dev/null @@ -1,846 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentArrayRelationshipLevelRelatedLink = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.2" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - } - // Removing to generate a failing scenario for rule `fetching-data-fetching-resources-single-relationship-level-related-link` - // "related": { - // "type": "string", - // "format": "uri" - // } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentArrayRelationshipLevelRelatedLink; diff --git a/test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleLevelSelfLink.js b/test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleLevelSelfLink.js deleted file mode 100644 index 6fcf1d6..0000000 --- a/test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleLevelSelfLink.js +++ /dev/null @@ -1,846 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleLevelSelfLink = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.2" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "links": { - "type": "object", - "properties": { - // Removing the `self` member to generate a failing scenario for rule `fetching-data-fetching-resources-single-level-self-link` - "fail": { - "type": "string", - "format": "uri" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleLevelSelfLink; diff --git a/test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleRelationshipLevelRelatedLink.js b/test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleRelationshipLevelRelatedLink.js deleted file mode 100644 index 552f18b..0000000 --- a/test/docs/fetchingData/fetchingResources/invalidApiDocumentSingleRelationshipLevelRelatedLink.js +++ /dev/null @@ -1,846 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentSingleRelationshipLevelRelatedLink = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.2" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - } - // Removing to generate a failing scenario for rule `fetching-data-fetching-resources-single-relationship-level-related-link` - // "related": { - // "type": "string", - // "format": "uri" - // } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentSingleRelationshipLevelRelatedLink; diff --git a/test/docs/fetchingData/fetchingResources/invalidApiDocumentTopLevelLinks.js b/test/docs/fetchingData/fetchingResources/invalidApiDocumentTopLevelLinks.js deleted file mode 100644 index 2e4ef20..0000000 --- a/test/docs/fetchingData/fetchingResources/invalidApiDocumentTopLevelLinks.js +++ /dev/null @@ -1,837 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -const invalidApiDocumentTopLevelLinks = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.2" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - // Removing this member to generate a failing scenario for rule `fetching-data-fetching-resources-top-level-links` - // "self": { - // "type": "string", - // "format": "uri" - // }, - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default invalidApiDocumentTopLevelLinks; diff --git a/test/docs/utilsTests/mockApiDocument.js b/test/docs/utilsTests/mockApiDocument.js deleted file mode 100644 index 97c01d2..0000000 --- a/test/docs/utilsTests/mockApiDocument.js +++ /dev/null @@ -1,92 +0,0 @@ -const mockApiDocument = { - 'openapi': '3.1.0', - 'info': { - 'title': 'User Information API', - 'version': '1.0.0', - 'description': 'API for retrieving user information' - }, - 'paths': { - '/users/{userId}': { - 'get': { - 'responses': { - '400': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - '$ref': '#/components/schemas/JsonApiError' - } - } - } - } - } - } - } - }, - 'components': { - 'schemas': { - 'JsonApiError': { - 'type': 'object', - 'properties': { - 'errors': { - 'type': 'array', - 'items': { - '$ref': '#/components/schemas/ErrorObject' - } - } - } - }, - 'ErrorObject': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'links': { - 'type': 'object', - 'properties': { - 'about': { - 'type': 'string', - 'format': 'uri' - } - } - }, - 'status': { - 'type': 'string' - }, - 'code': { - 'type': 'string' - }, - 'title': { - 'type': 'string' - }, - 'detail': { - 'type': 'string' - }, - 'source': { - 'type': 'object', - 'properties': { - 'pointer': { - 'type': 'string' - }, - 'parameter': { - 'type': 'string' - }, - 'header': { - 'type': 'string' - } - } - }, - 'meta': { - 'type': 'object', - 'additionalProperties': true - } - }, - 'required': [ - 'detail' - ] - } - } - } -}; - -export default mockApiDocument; diff --git a/test/docs/validApiDocument.js b/test/docs/validApiDocument.js deleted file mode 100644 index 29d1f5a..0000000 --- a/test/docs/validApiDocument.js +++ /dev/null @@ -1,886 +0,0 @@ -/* eslint-env mocha */ -/* eslint-disable quotes */ -/** - * This validApiDocument is utilized for a centralized dereferencing document which is used in test suites as a global scope. - * This will provide performance optimiation and resolve any issues related to mutliple derferencing. - * - * Key Reason: - * 1. Performance Optimization: - * - As our API template grows, the number of test cases that require a dereferenced version of validApiDocument is increasing. - * - Previously, each test file was individually dereferencing this document, which is a resource-intensive process. - * By dereferencing it once globally, we reduce the computational overhead significantly. - * - This global approach ensures that all tests use the same dereferenced instance, improving the overall efficiency of our - * test execution. - * 2. Resolving Multiple Dereferencing Issues: - * - In our prior setup, attempting to dereference an already dereferenced document in different test files led to inconsistencies - * and potential errors. - * - By having a single, globally dereferenced document, we eliminate the risk of such issues. This ensures that all tests work - * with a consistent and stable version of the API document. - * 3. Maintainability and Consistency: - * - This refactor simplifies the test setup by removing redundant dereferencing logic in multiple files. - * - It also enhances the consistency across our test suites, making it easier for the team to write and maintain tests. - * - * Use Case: - * - Inside of your test case suite you will need to create a variable that will call the globally scoped document - * - @see {@link ../jsonapi-fetching-data-fetching-resources.test.js} for live usage - * - Below is a setup example: - * - * - * describe('your-custom-rule-file ruleset:', function yourCustomTestSuite() { - * - * let dereferenceValidApiDocument; - * - * before(function () { - * - * // Access the globally dereferenced document - * dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - * - * }); - * - * }); - * - */ -const validApiDocument = { - "openapi": "3.1.0", - "info": { - "title": "OpenAPI Management Template", - "description": "This API manages information pertaining to users\nwhich is adhereing to JSON:API v1.0 standards. The goal of this template is\nto provide a universal temaplte for testing all of the JSON:API v1.0\nspecifications. This document adheres to the following sections:\n - ContentNegotiation.ClientResponsibilities\n - ContentNegotiation.ServerResponsibilities\n - DocumentStructure\n - DocumentStructure.TopLevel\n - DocumentStructure.ResourceObjects\n - DocumentStructure.ResourceObjects.Attributes\n - DocumentStructure.Links\n - DocumentStructure.MetaInformation\n - DocumentStructure.MemberNames\n - FetchingData.FetchingResources\n - FetchingData.Sorting\n - FetchingData.Pagination\n - FetchingData.Filtering\n - Errors.ProcessingErrors\n - Errors.ErrorObjects", - "version": "1.2.3" - }, - "servers": [ - { - "url": "https://api.template.com/v1" - } - ], - "x-jsonapi-object": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "paths": { - "/users": { - "get": { - "tags": [ - "users" - ], - "summary": "List all users", - "description": "Retrieve a list of users with pagination and optional filters for sorting and searching.", - "security": [], - "responses": { - "200": { - "description": "A list of users", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserListResponse" - }, - "examples": { - "userListExample": { - "summary": "Example response for user list", - "value": { - "data": [ - { - "type": "users", - "id": "1", - "attributes": { - "name": "John Doe", - "email": "john@example.com" - } - } - ] - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-102", - "status": "400", - "title": "Bad Request", - "detail": "The request is invalid." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "page[number]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 1 - }, - "description": "Page number for pagination" - }, - { - "name": "page[size]", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1, - "default": 20 - }, - "description": "Number of items per page" - }, - { - "name": "filter", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Filter string to narrow down the search" - }, - { - "name": "sort", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Sorting criteria. E.g., `name,-email` for ascending by name and descending by email." - }, - { - "name": "fields", - "in": "query", - "schema": { - "type": "string" - }, - "description": "Comma-separated list of fields to include in the response." - } - ] - }, - "post": { - "tags": [ - "users" - ], - "summary": "Create a new user", - "requestBody": { - "description": "Payload to create a new user, containing user details.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "201": { - "description": "New user created", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request - Indicates that the server cannot process the request due to a client error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-701", - "status": "400", - "title": "Bad Request", - "detail": "The request could not be processed due to malformed syntax.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal server error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-902", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/400" - } - } - ] - } - } - } - } - } - } - } - } - }, - "/users/{userId}": { - "get": { - "tags": [ - "users" - ], - "summary": "Get User by ID", - "security": [], - "description": "Retrieves information for a specific user by their ID.", - "operationId": "getUserById", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "description": "Unique identifier of the user", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Details of a user", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - }, - "examples": { - "user": { - "summary": "User Example", - "value": { - "data": { - "id": "12345", - "type": "user", - "attributes": { - "name": "John Doe", - "email": "john.doe@example.com" - } - } - } - } - } - } - } - }, - "404": { - "description": "User Not Found", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFound": { - "summary": "Example of a not found error", - "value": { - "errors": { - "id": "error-444", - "status": "404", - "title": "Not Found", - "detail": "The requested resource was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "users" - ], - "summary": "Update a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Payload to update an existing user.", - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User updated", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/UserResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequestExample": { - "summary": "Example of a Bad Request response", - "value": { - "errors": [ - { - "status": 400, - "title": "Bad Request", - "detail": "The request payload is invalid. Please check the request data." - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "badRequest": { - "summary": "Example of a bad request error", - "value": { - "errors": [ - { - "id": "error-032", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/500" - } - } - ] - } - } - } - } - } - } - } - }, - "delete": { - "tags": [ - "users" - ], - "summary": "Delete a user", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The user was successfully deleted." - }, - "404": { - "description": "The specified user was not found.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "notFoundError": { - "summary": "Example of a 404 Not Found error", - "value": { - "errors": [ - { - "id": "error-123", - "status": "404", - "title": "Not Found", - "detail": "The user with the specified ID was not found.", - "links": { - "about": "https://api.usermanagement.com/docs/errors/404" - } - } - ] - } - } - } - } - } - }, - "500": { - "description": "Internal Server Error - Indicates a server-side error.", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/JsonApiError" - }, - "examples": { - "internalServerErrorExample": { - "summary": "Example of an internal server error response", - "value": { - "errors": [ - { - "id": "error-500", - "status": "500", - "title": "Internal Server Error", - "detail": "The server encountered an unexpected condition that prevented it from fulfilling the request." - } - ] - } - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the user" - }, - "type": { - "type": "string", - "description": "Type of the resource (users)" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - }, - "links": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - } - } - }, - "relationships": { - "type": "object", - "properties": { - "posts": { - "$ref": "#/components/schemas/RelationshipLinks" - } - } - } - } - }, - "UserResponse": { - "type": "object", - "description": "Response schema for a single user or a newly created user.", - "properties": { - "data": { - "$ref": "#/components/schemas/User" - }, - "included": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RelatedResource" - } - }, - "meta": { - "$ref": "#/components/schemas/Meta" - } - } - }, - "UserListResponse": { - "type": "object", - "description": "Response schema for a list of users with pagination details.", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "links": { - "$ref": "#/components/schemas/PaginationLinks" - } - } - }, - "UserRequest": { - "type": "object", - "description": "Request schema for creating a new user.", - "properties": { - "data": { - "type": "object", - "required": [ - "type", - "attributes" - ], - "properties": { - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserUpdateRequest": { - "type": "object", - "description": "Request schema for updating an existing user's details.", - "properties": { - "data": { - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - } - } - }, - "UserAttributes": { - "type": "object", - "required": [ - "name", - "email" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "Email address of the user, must follow standard email format." - }, - "role": { - "type": "string", - "description": "Role of the user in the system" - } - } - }, - "RelationshipLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "related": { - "type": "string", - "format": "uri" - } - } - }, - "RelatedResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "$ref": "#/components/schemas/UserAttributes" - } - } - }, - "Meta": { - "type": "object", - "properties": { - "totalCount": { - "type": "integer", - "description": "Total number of resources available." - }, - "lastUpdated": { - "type": "string", - "format": "date-time", - "description": "The timestamp of the last update." - } - } - }, - "PaginationLinks": { - "type": "object", - "properties": { - "self": { - "type": "string", - "format": "uri" - }, - "first": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the first page of data. Null if not available." - }, - "last": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the last page of data. Null if not available." - }, - "prev": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the previous page of data. Null if not available." - }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The link to the next page of data. Null if not available." - } - } - }, - "JsonApiError": { - "type": "object", - "required": [ - "errors" - ], - "properties": { - "errors": { - "type": "array", - "maxItems": 1, - "items": { - "$ref": "#/components/schemas/ErrorObject" - } - } - } - }, - "ErrorObject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "links": { - "type": "object", - "properties": { - "about": { - "type": "string", - "format": "uri" - } - } - }, - - /** - * Commonly used HTTP status codes: - * - * `400` Bad Request: The request was unacceptable, often due o missing a required parameter - * `401` Unauthorized: No valid authentication credentials provided. - * `403` Forbidden: The client does not have access rights to the content. - * `404` Not Found: The requested resource does not exist. - * `406` Not Acceptable: The requested format is not available. - * `409` Conflict: The request could not be completed due to a conflict. - * `422` Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors. - * `500` Internal Server Error: A generic error message for unexpected server errors. - * `502` Bad Gateway: The server received an invalid response from the upstream server. - * `503` Service Unavailable: The server is currently unavailable (overloaded or down). - */ - "status": { - "type": "string", - "enum": [ - "400", - "401", - "403", - "404", - "405", - "406", - "409", - "422", - "500", - "502", - "503" - ], - "description": "HTTP status code applicable to this error, given as a string value." - }, - "code": { - "type": "string" - }, - "title": { - "type": "string" - }, - "detail": { - "type": "string" - }, - "source": { - "type": "object", - "properties": { - "pointer": { - "type": "string" - }, - "parameter": { - "type": "string" - } - } - }, - "meta": { - "type": "object", - "additionalProperties": true - } - } - } - }, - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Bearer token authentication" - }, - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "X-API-KEY", - "description": "API Key based authentication" - } - } - }, - "security": [ - { - "BearerAuth": [] - }, - { - "ApiKeyAuth": [] - } - ] -}; - -export default validApiDocument; diff --git a/test/jsonapi-content-negotiation-clients.test.js b/test/jsonapi-content-negotiation-clients.test.js deleted file mode 100644 index 463d69b..0000000 --- a/test/jsonapi-content-negotiation-clients.test.js +++ /dev/null @@ -1,141 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-content-negotiation-clients.js'; - -describe('jsonapi-content-negotiation-clients ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('request-content-type:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - openapi: '3.0.2', - paths: { - '/junk': { - patch: { - requestBody: { - content: { - 'application/vnd.api+json': { - schema: { - type: 'string' - } - }, - 'application/json': { - schema: { - type: 'string' - } - } - } - } - } - }, - '/stuff': { - patch: { - requestBody: { - content: { - 'application/vnd.api+json': { - schema: { - type: 'string' - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['request-content-type'].given; - const expectedPaths = [ - doc.paths['/junk'].patch.requestBody.content, - doc.paths['/stuff'].patch.requestBody.content - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "request-content-type" errors if request content-type is not JSON:API', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /junk: - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: string - application/json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('request-content-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//junk/patch/requestBody/content/application/json', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-content-negotiation-servers.test.js b/test/jsonapi-content-negotiation-servers.test.js deleted file mode 100644 index 56de4a1..0000000 --- a/test/jsonapi-content-negotiation-servers.test.js +++ /dev/null @@ -1,428 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-content-negotiation-servers.js'; - -describe('jsonapi-content-negotiation-servers ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('response-content-type:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - } - } - }, - '201': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - } - } - }, - '202': { - 'content': { - 'application/json': { - 'schema': { - 'type': 'string' - } - } - } - }, - '203': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - }, - 'application/json': { - 'schema': { - 'type': 'string' - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['response-content-type'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content, - doc.paths['/stuff'].get.responses[201].content, - doc.paths['/stuff'].get.responses[202].content, - doc.paths['/stuff'].get.responses[203].content - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(4, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "response-content-type" errors if response content-type is not JSON:API', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - '201': - content: - application/vnd.api+json: - schema: - type: string - '202': - content: - application/json: - schema: - type: string - '203': - content: - application/vnd.api+json: - schema: - type: string - application/json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['415-406-response-codes']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('response-content-type', 'Incorrect error'); - expect(results[1].code).to.equal('response-content-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/202/content/application/json', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/203/content/application/json', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - '201': - content: - application/vnd.api+json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['415-406-response-codes']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('415-406-response-codes', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - } - } - }, - '201': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - } - } - }, - '202': { - 'content': { - 'application/json': { - 'schema': { - 'type': 'string' - } - } - } - }, - '203': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - }, - 'application/json': { - 'schema': { - 'type': 'string' - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['415-406-response-codes'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(1, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return a "415-406-response-codes" error when missing a 415 AND 406 response', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - '201': - content: - application/vnd.api+json: - schema: - type: string - '202': - content: - application/json: - schema: - type: string - '203': - content: - application/vnd.api+json: - schema: - type: string - application/json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['response-content-type']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('415-406-response-codes', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should return a "415-406-response-codes" error when missing a 415 response', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - '406': - content: - application/vnd.api+json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['response-content-type']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('415-406-response-codes', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should return a "415-406-response-codes" error when missing a 406 response', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - '415': - content: - application/vnd.api+json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['response-content-type']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('415-406-response-codes', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - '415': - content: - application/vnd.api+json: - schema: - type: string - '406': - content: - application/vnd.api+json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['response-content-type']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-jsonapi-object.test.js b/test/jsonapi-document-structure-jsonapi-object.test.js deleted file mode 100644 index 719c435..0000000 --- a/test/jsonapi-document-structure-jsonapi-object.test.js +++ /dev/null @@ -1,187 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-document-structure-jsonapi-object.js'; - -describe('jsonapi-document-structure-jsonapi-object ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('jsonapi-object-schema:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {} - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object' - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['jsonapi-object-schema'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.jsonapi - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(1, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "jsonapi-object-schema" errors if jsonapi object doesn\'t match schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - jsonapi: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - jsonapi: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: true - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 2'); - expect(results[0].code).to.equal('jsonapi-object-schema', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('//stuff/patch', 'Wrong path'); - expect(results[0].path.join('/')).to.include('/jsonapi', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - jsonapi: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: false - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - jsonapi: - type: object - properties: - version: - type: string - meta: - type: object - additionalProperties: true - additionalProperties: false - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-links.test.js b/test/jsonapi-document-structure-links.test.js deleted file mode 100644 index 0ce270b..0000000 --- a/test/jsonapi-document-structure-links.test.js +++ /dev/null @@ -1,812 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-document-structure-links.js'; - -describe('jsonapi-content-negotiation-servers ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('links-object:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': {} - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': {} - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['links-object'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.links, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.links - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "links-object" errors if links object doesn\'t match schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: string - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['links-object-schema-type']; - delete spectral.ruleset.rules['links-object-schema-properties']; - delete spectral.ruleset.rules['links-object-schema-properties-href']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('links-object', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/links/type', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/links/type', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['links-object-schema-type']; - delete spectral.ruleset.rules['links-object-schema-properties']; - delete spectral.ruleset.rules['links-object-schema-properties-href']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('links-object-schema-type:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': { - 'type': 'object', - 'properties': { - 'self': {}, - 'related': { - 'type': 'object', - 'properties': { - 'href': {}, - 'meta': {} - } - } - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': { - 'type': 'object', - 'properties': { - 'next': {} - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['links-object-schema-type'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.links.properties.self, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.links.properties.related, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.links.properties.next - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "links-object-schema-type" errors if links object doesn\'t match schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: string - next: - type: number - related: - type: object - properties: - href: - type: string - meta: - type: object - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: number - related: - type: object - properties: - href: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['links-object']; - delete spectral.ruleset.rules['links-object-schema-properties']; - delete spectral.ruleset.rules['links-object-schema-properties-href']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('links-object-schema-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/links/properties/next/type', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/links/properties/self/type', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: string - next: - type: string - related: - type: object - properties: - href: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('links-object-schema-properties:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': { - 'type': 'object', - 'properties': { - 'self': {}, - 'related': { - 'type': 'object', - 'properties': { - 'href': {}, - 'meta': {} - } - } - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': { - 'type': 'object', - 'properties': { - 'next': { - 'type': 'object', - 'properties': { - 'href': {}, - 'meta': {} - } - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['links-object-schema-properties'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.links.properties.related.properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.links.properties.next.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "links-object-schema-properties" errors if links object doesn\'t match schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: string - next: - type: string - related: - type: object - properties: - foo: - type: string - meta: - type: object - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - next: - type: object - properties: - foo: - type: string - meta: - type: object - another: - type: object - properties: - href: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['links-object']; - delete spectral.ruleset.rules['links-object-schema-type']; - delete spectral.ruleset.rules['links-object-schema-properties-href']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('links-object-schema-properties', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/links/properties/related/properties', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/links/properties/next/properties', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: string - next: - type: string - related: - type: object - properties: - href: - type: string - meta: - type: object - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - next: - type: object - properties: - href: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('links-object-schema-properties-href:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': { - 'type': 'object', - 'properties': { - 'self': {}, - 'related': { - 'type': 'object', - 'properties': { - 'href': {}, - 'meta': {} - } - } - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'links': { - 'type': 'object', - 'properties': { - 'next': { - 'type': 'object', - 'properties': { - 'href': {}, - 'meta': {} - } - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['links-object-schema-properties-href'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.links.properties.related.properties.href, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.links.properties.next.properties.href - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "links-object-schema-properties" errors if links object doesn\'t match schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: string - next: - type: string - related: - type: object - properties: - href: - type: number - meta: - type: object - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - next: - type: object - properties: - foo: - type: string - meta: - type: object - another: - type: object - properties: - href: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['links-object']; - delete spectral.ruleset.rules['links-object-schema-type']; - delete spectral.ruleset.rules['links-object-schema-properties']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('links-object-schema-properties-href', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/links/properties/related/properties/href', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - self: - type: string - next: - type: string - related: - type: object - properties: - href: - type: string - meta: - type: object - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - properties: - next: - type: object - properties: - href: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-meta-information.test.js b/test/jsonapi-document-structure-meta-information.test.js deleted file mode 100644 index 18ccb5c..0000000 --- a/test/jsonapi-document-structure-meta-information.test.js +++ /dev/null @@ -1,174 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-document-structure-meta-information.js'; - -describe('jsonapi-document-structure-meta-information ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('meta-object-schema:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['meta-object-schema'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.meta, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties['data:'].properties.meta, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.meta - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "meta-object-schema" errors if meta object doesn\'t match schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - meta: - type: string - - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - meta: - type: object - properties: - meta: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('meta-object-schema', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/meta/type', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/meta/properties/meta/type', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - meta: - type: object - properties: - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-attributes.test.js b/test/jsonapi-document-structure-resource-attributes.test.js deleted file mode 100644 index 239c429..0000000 --- a/test/jsonapi-document-structure-resource-attributes.test.js +++ /dev/null @@ -1,883 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-document-structure-resource-attributes.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo, debugDebug } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import invalidApiDocumentSingleType from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleType.js'; -import invalidApiDocumentSingleNoForeignKeys from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoForeignKeys.js'; -import invalidApiDocumentSingleNoRelationshipsMember from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoRelationshipsMember.js'; -import invalidApiDocumentSingleNoLinksMember from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentSingleNoLinksMember.js'; -import invalidApiDocumentArrayAttributesType from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayAttributesType.js'; -import invalidApiDocumentArrayNoForeignKeys from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoForeignKeys.js'; -import invalidApiDocumentArrayNoRelationshipsMember from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoRelationshipsMember.js'; -import invalidApiDocumentArrayNoLinksMember from './docs/documentStructure/resourceObjects/attributes/invalidApiDocumentArrayNoLinksMember.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API DocumentStructure.Resource.Attributes ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-document-structure-resource-attributes.js - * against various OpenAPI documents that are valid based on JSON: API v1.0 standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset - * and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks if - * the provided error is an instance of AggregateError. If so, it iterates over each individual error within the aggregate - * and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility is particularly - * useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, - * resolving all $ref references found within. It supports nested structures and arrays, handles circular references, and - * keeps resolved references from the components section for when they are needed at a later time. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ -describe('jsonapi-document-structure-resource-attributes ruleset:', function documentStructureResourceAttributesSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - // Access the globally dereferenced document - dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - - }); - - /** - * Ruleset: document-structure-resource-single-attributes-type - */ - describe('document-structure-resource-single-attributes-type:', function documentStructureResourceSingleAttributesType() { - - const testingRuleName = 'document-structure-resource-single-attributes-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleAttributesTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleAttributesTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleType, invalidApiDocumentSingleType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleAttributesTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-single-attributes-no-foreign-keys - */ - describe('document-structure-resource-single-attributes-no-foreign-keys:', function documentStructureResourceSingleAttributesNoForeignKeys() { - - const testingRuleName = 'document-structure-resource-single-attributes-no-foreign-keys'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleAttributesNoForeignKeysPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleAttributesNoForeignKeysFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleNoForeignKeys, invalidApiDocumentSingleNoForeignKeys); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleAttributesNoForeignKeysPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-single-attributes-no-relationships-member - */ - describe('document-structure-resource-single-attributes-no-relationships-member:', function documentStructureResourceSingleAttributesNoRelationshipsMember() { - - const testingRuleName = 'document-structure-resource-single-attributes-no-relationships-member'; - - // Utilizing an invalid API Document since `relationships` member is not allowed to be present in an `attributes` member object. - let dereferencedOpenApiDocumentSingleNoRelationshipsMember; - - before(function beforeNoRelationsMember() { - - dereferencedOpenApiDocumentSingleNoRelationshipsMember = resolveRef(invalidApiDocumentSingleNoRelationshipsMember, invalidApiDocumentSingleNoRelationshipsMember); - - }); - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleAttributesNoRelationshipsMemberPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocumentNoRelationshipsMember,null,2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferencedOpenApiDocumentSingleNoRelationshipsMember.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.relationships }, - { expected: dereferencedOpenApiDocumentSingleNoRelationshipsMember.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.relationships }, - { expected: dereferencedOpenApiDocumentSingleNoRelationshipsMember.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.relationships }, - { expected: dereferencedOpenApiDocumentSingleNoRelationshipsMember.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.relationships }, - { expected: dereferencedOpenApiDocumentSingleNoRelationshipsMember.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.relationships } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferencedOpenApiDocumentSingleNoRelationshipsMember }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleAttributesNoRelationshipsMemberFailure() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocumentNoRelationshipsMember,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocumentSingleNoRelationshipsMember, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleAttributesNoRelationshipsMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-single-attributes-no-links-member - */ - describe('document-structure-resource-single-attributes-no-links-member:', function documentStructureResourceSingleAttributesLinksMember() { - - const testingRuleName = 'document-structure-resource-single-attributes-no-links-member'; - - // Utilizing an invalid API Document since `links` member is not allowed to be present in an `attributes` member object. - let dereferencedOpenApiDocumentSingleNoLinksMember; - - before(function beforeNoLinksMember() { - - dereferencedOpenApiDocumentSingleNoLinksMember = resolveRef(invalidApiDocumentSingleNoLinksMember, invalidApiDocumentSingleNoLinksMember); - - }); - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleAttributesNoLinksMemberPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferencedOpenApiDocumentSingleNoLinksMember.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.links }, - { expected: dereferencedOpenApiDocumentSingleNoLinksMember.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.links }, - { expected: dereferencedOpenApiDocumentSingleNoLinksMember.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.links }, - { expected: dereferencedOpenApiDocumentSingleNoLinksMember.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.links }, - { expected: dereferencedOpenApiDocumentSingleNoLinksMember.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties.links } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferencedOpenApiDocumentSingleNoLinksMember }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleAttributesNoLinksMemberFailure() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocumentSingleNoLinksMember, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleAttributesNoLinksMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-attributes-type - */ - describe('document-structure-resource-array-attributes-type:', function documentStructureResourceArrayAttributesType() { - - const testingRuleName = 'document-structure-resource-array-attributes-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayAttributesTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.attributes } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayAttributesTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayAttributesType, invalidApiDocumentArrayAttributesType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayAttributesTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-attributes-no-foreign-keys - */ - describe('document-structure-resource-array-attributes-no-foreign-keys:', function documentStructureResourceArrayAttributesNoForeignKeys() { - - const testingRuleName = 'document-structure-resource-array-attributes-no-foreign-keys'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayAttributesNoForeignKeysPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.attributes.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayAttributesNoForeignKeysFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayNoForeignKeys, invalidApiDocumentArrayNoForeignKeys); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayAttributesNoForeignKeysPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-attributes-no-relationships-member - */ - describe('document-structure-resource-array-attributes-no-relationships-member:', function documentStructureResourceArrayAttributesNoRelationshipsMember() { - - const testingRuleName = 'document-structure-resource-array-attributes-no-relationships-member'; - - // Utilizing an invalid API Document since `relationships` member is not allowed to be present in an `attributes` member object. - let dereferencedOpenApiDocumentArrayNoRelationshipsMember; - - before(function beforeNoRelationsMember() { - - dereferencedOpenApiDocumentArrayNoRelationshipsMember = resolveRef(invalidApiDocumentArrayNoRelationshipsMember, invalidApiDocumentArrayNoRelationshipsMember); - - }); - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayAttributesNoRelationshipsMemberPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocumentNoRelationshipsMember,null,2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferencedOpenApiDocumentArrayNoRelationshipsMember.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.attributes.properties.relationships } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferencedOpenApiDocumentArrayNoRelationshipsMember }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayAttributesNoRelationshipsMemberFailure() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocumentNoRelationshipsMember,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocumentArrayNoRelationshipsMember, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayAttributesNoRelationshipsMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-attributes-no-links-member - */ - describe('document-structure-resource-array-attributes-no-links-member:', function documentStructureResourceArrayAttributesLinksMember() { - - const testingRuleName = 'document-structure-resource-array-attributes-no-links-member'; - - // Utilizing an invalid API Document since `links` member is not allowed to be present in an `attributes` member object. - let dereferencedOpenApiDocumentArrayNoLinksMember; - - before(function beforeNoLinksMember() { - - dereferencedOpenApiDocumentArrayNoLinksMember = resolveRef(invalidApiDocumentArrayNoLinksMember, invalidApiDocumentArrayNoLinksMember); - - }); - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayAttributesNoLinksMemberPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferencedOpenApiDocumentArrayNoLinksMember.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.attributes.properties.links } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferencedOpenApiDocumentArrayNoLinksMember }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayAttributesNoLinksMemberFailure() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocumentArrayNoLinksMember, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayAttributesNoLinksMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-attributes.test.js.old b/test/jsonapi-document-structure-resource-attributes.test.js.old deleted file mode 100644 index 93ff26b..0000000 --- a/test/jsonapi-document-structure-resource-attributes.test.js.old +++ /dev/null @@ -1,445 +0,0 @@ -'use strict'; - -const {join} = require('path'); -const {expect} = require('chai'); -const {Spectral, Document, Parsers} = require('@stoplight/spectral'); -const {JSONPath} = require('jsonpath-plus'); - -const RULESET_FILE = join(__dirname, '../rules/jsonapi-document-structure-resource-attributes.yaml'); - -describe('jsonapi-document-structure-top-level ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('document-strucuture-resource-attributes-type', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'attributes': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'attributes': {} - } - }, - 'included': { - 'type': 'object', - 'properties': { - 'attributes': {} - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$..properties[?(@property === 'attributes')]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.attributes, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.included.properties.attributes - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return resource attribute type errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - properties: - attributes: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - included: - properties: - attributes: - type: string - /junk: - patch: - requestBody: - content: - application/json: - schema: - type: object - properties: - data: - properties: - attributes: - type: string - - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['attributes-object-properties']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('attributes-object-type', 'Incorrect error'); - expect(results[1].code).to.equal('attributes-object-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/included/properties/attributes/type', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//junk/patch/requestBody/content/application/json/schema/properties/data/properties/attributes/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - properties: - attributes: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - included: - properties: - attributes: - type: object - /junk: - patch: - requestBody: - content: - application/json: - schema: - type: object - properties: - data: - properties: - attributes: - type: object - - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['attributes-object-properties']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('document-strucuture-resource-attributes-properties', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'attributes': { - 'properties': {} - } - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'attributes': { - 'properties': {} - } - } - }, - 'included': { - 'type': 'object', - 'properties': { - 'attributes': { - 'properties': {} - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$..properties[?(@property === 'attributes')].properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.included.properties.attributes.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return resource attribute property errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - properties: - attributes: - type: object - properties: - name: {} - relationships: {} - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - included: - properties: - attributes: - type: object - properties: - links: {} - /junk: - patch: - requestBody: - content: - application/json: - schema: - type: object - properties: - data: - properties: - attributes: - type: object - properties: - name: {} - description: {} - - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['attributes-object-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('attributes-object-properties', 'Incorrect error'); - expect(results[1].code).to.equal('attributes-object-properties', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties/attributes/properties/relationships', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/included/properties/attributes/properties/links', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - properties: - attributes: - type: object - properties: - name: {} - description: {} - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - included: - properties: - attributes: - type: object - properties: - property1: {} - property2: {} - - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['attributes-object-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-fields.test.js b/test/jsonapi-document-structure-resource-fields.test.js deleted file mode 100644 index 07c43f0..0000000 --- a/test/jsonapi-document-structure-resource-fields.test.js +++ /dev/null @@ -1,159 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-document-structure-resource-fields.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo, debugDebug } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import invalidApiDocumentNoTypeOrId from './docs/documentStructure/resourceObjects/fields/invalidApiDocumentNoTypeOrId.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API DocumentStructure.Resource.Fields ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-document-structure-resource-fields.js - * against various OpenAPI documents that are valid based on JSON: API v1.0 standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset - * and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks if - * the provided error is an instance of AggregateError. If so, it iterates over each individual error within the aggregate - * and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility is particularly - * useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, - * resolving all $ref references found within. It supports nested structures and arrays, handles circular references, and - * keeps resolved references from the components section for when they are needed at a later time. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ -describe('jsonapi-document-structure-resource-fields ruleset:', function documentStructureResourceFieldsSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - // Access the globally dereferenced document - dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - - }); - - /** - * Ruleset: document-structure-resource-fields-no-type-or-id - */ - describe('document-structure-resource-fields-no-type-or-id:', function documentStructureResourceFieldsNoTypeOrId() { - - const testingRuleName = 'document-structure-resource-fields-no-type-or-id'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceFieldsNoTypeOrIdPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.items.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.items.properties.relationships.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses[201].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses[201].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.attributes.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceFieldsNoTypeOrIdFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentNoTypeOrId, invalidApiDocumentNoTypeOrId); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 20; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceFieldsNoTypeOrIdPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-identification.js.old b/test/jsonapi-document-structure-resource-identification.js.old deleted file mode 100644 index 2df76dc..0000000 --- a/test/jsonapi-document-structure-resource-identification.js.old +++ /dev/null @@ -1,393 +0,0 @@ -'use strict'; - -const {join} = require('path'); -const {expect} = require('chai'); -const {Spectral, Document, Parsers} = require('@stoplight/spectral'); -const {JSONPath} = require('jsonpath-plus'); - -const RULESET_FILE = join(__dirname, '../rules/jsonapi-document-structure-resource-identification.yaml'); - -describe('jsonapi-document-structure-resource-identification:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('jsonapi-document-structure-resource-identification-property', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': {}, - 'data': { - 'items': { - 'allOf': [ - { - 'properties': { - 'id': {}, - 'type': {} - } - } - ] - } - }, - 'included': { - 'items': { - 'allOf': [ - { - 'properties': { - 'id': {}, - 'type': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$..properties[?(@property === 'data' || @property === 'included')]..allOf.*.properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.items.allOf[0].properties, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[0].properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource-identification-property" errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - items: - allOf: - - properties: - foo: - type: string - id: - type: string - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - included: - items: - allOf: - - properties: - type: - type: string - foo: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing. - .then(() => { - - //delete spectral.rules['']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('resource-identification-property', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/items/allOf/0/properties/foo', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/included/items/allOf/0/properties/foo', 'Wrong path'); - - - done(); - - }); - - }); - - it('the rule should return no type errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - items: - allOf: - - properties: - type: - type: string - id: - type: string - - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['error-object-properties']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-document-structure-resource-identification-type', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': {}, - 'data': { - 'items': { - 'allOf': [ - { - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - } - } - } - ] - } - }, - 'included': { - 'items': { - 'allOf': [ - { - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - } - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$..properties[?(@property === 'data' || @property === 'included')]..allOf.*.properties[?(@property === 'id' || @property === 'type')]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.items.allOf[0].properties.id, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.items.allOf[0].properties.type, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[0].properties.id, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[0].properties.type - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(4, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource-identification-type" errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - items: - allOf: - - properties: - foo: - type: string - id: - type: object - - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - included: - items: - allOf: - - properties: - type: - type: object - foo: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing. - .then(() => { - - //delete spectral.rules['']; - delete spectral.rules['resource-identification-property']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('resource-identification-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.include('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/items/allOf/0/properties/id/type', 'Wrong path'); - expect(results[1].path.join('/')).to.include('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/included/items/allOf/0/properties/type', 'Wrong path'); - - - done(); - - }); - - }); - - it('the rule should return no type errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - items: - allOf: - - properties: - type: - type: string - id: - type: string - - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-identification-property']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-identification.test.js b/test/jsonapi-document-structure-resource-identification.test.js deleted file mode 100644 index 88944a9..0000000 --- a/test/jsonapi-document-structure-resource-identification.test.js +++ /dev/null @@ -1,912 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-document-structure-resource-identification.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo, debugDebug } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import invalidApiDocumentSingleIdMember from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdMember.js'; -import invalidApiDocumentSingleIdType from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleIdType.js'; -import invalidApiDocumentSingleTypeMember from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeMember.js'; -import invalidApiDocumentSingleTypeType from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentSingleTypeType.js'; -import invalidApiDocumentArrayIdMember from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdMember.js'; -import invalidApiDocumentArrayIdType from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayIdType.js'; -import invalidApiDocumentArrayTypeMember from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeMember.js'; -import invalidApiDocumentArrayTypeType from './docs/documentStructure/resourceObjects/identification/invalidApiDocumentArrayTypeType.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API DocumentStructure.Resource.identification ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-document-structure-resource-identification.js - * against various OpenAPI documents that are valid based on JSON: API v1.0 standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset - * and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks if - * the provided error is an instance of AggregateError. If so, it iterates over each individual error within the aggregate - * and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility is particularly - * useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, - * resolving all $ref references found within. It supports nested structures and arrays, handles circular references, and - * keeps resolved references from the components section for when they are needed at a later time. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ - -describe('jsonapi-document-structure-resource-identification ruleset:', function documentStructureResourceIdentificationSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - // Access the globally dereferenced document - dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - - }); - - /** - * Ruleset: document-structure-resource-single-identification-id-member - */ - describe('document-structure-resource-single-identification-id-member:', function documentStructureResourceSingleIdentificationIdMember() { - - const testingRuleName = 'document-structure-resource-single-identification-id-member'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleIdentificationIdMemberPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpressions = ruleset.rules[testingRuleName].given; - // debugDebug(`JSONPath Expression: ${jsonPathExpressions}`); - - const expectedExpressionPaths = [ - [ - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties } - ], - [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties } - ] - ]; - - jsonPathExpressions.forEach((jsonPathExpression, exprIndex) => { - - debugDebug(`JSONPath Expression [${exprIndex}]: ${jsonPathExpression}`); - - const expectedPaths = expectedExpressionPaths[exprIndex]; - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - // Check if the number of results matches the expected number for this expression - expect(result.length).to.equal(expectedPaths.length, `\x1b[31mExpected ${expectedPaths.length} elements to match in the OpenAPI Document for expression array index [${exprIndex}].\x1b[0m\n`); - - expectedPaths.forEach((path, pathIndex) => { - - // Additional checks for each path - debugInfo(`Element ${pathIndex + 1} found from JSONPath Expression array index [${exprIndex}]: \x1b[32m${JSON.stringify(result[pathIndex], null, 2)}`); - - // Check if each result matches the corresponding expected path - expect(result[pathIndex]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${pathIndex + 1}\x1b[0m`); - - }); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleIdentificationIdMemberFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleIdMember, invalidApiDocumentSingleIdMember); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 4; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleIdentificationIdMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-single-identification-id-type - */ - describe('document-structure-resource-single-identification-id-type:', function documentStructureResourceSingleIdentificationIdType() { - - const testingRuleName = 'document-structure-resource-single-identification-id-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleIdentificationIdTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpressions = ruleset.rules[testingRuleName].given; - // debugDebug(`JSONPath Expression: ${jsonPathExpressions}`); - - const expectedExpressionPaths = [ - [ - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.id } - ], - [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.id } - ] - ]; - - jsonPathExpressions.forEach((jsonPathExpression, exprIndex) => { - - debugDebug(`JSONPath Expression [${exprIndex}]: ${jsonPathExpression}`); - - const expectedPaths = expectedExpressionPaths[exprIndex]; - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - // Check if the number of results matches the expected number for this expression - expect(result.length).to.equal(expectedPaths.length, `\x1b[31mExpected ${expectedPaths.length} elements to match in the OpenAPI Document for expression array index [${exprIndex}].\x1b[0m\n`); - - expectedPaths.forEach((path, pathIndex) => { - - // Additional checks for each path - debugInfo(`Element ${pathIndex + 1} found from JSONPath Expression array index [${exprIndex}]: \x1b[32m${JSON.stringify(result[pathIndex], null, 2)}`); - - // Check if each result matches the corresponding expected path - expect(result[pathIndex]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${pathIndex + 1}\x1b[0m`); - - }); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleIdentificationIdTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleIdType, invalidApiDocumentSingleIdType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 4; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleIdentificationIdTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-single-identification-type-member - */ - describe('document-structure-resource-single-identification-type-member:', function documentStructureResourceSingleIdentificationTypeMember() { - - const testingRuleName = 'document-structure-resource-single-identification-type-member'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleIdentificationTypeMemberPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleIdentificationTypeMemberFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleTypeMember, invalidApiDocumentSingleTypeMember); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleIdentificationTypeMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-single-identification-type-type - */ - describe('document-structure-resource-single-identification-type-type:', function documentStructureResourceSingleIdentificationTypeType() { - - const testingRuleName = 'document-structure-resource-single-identification-type-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceSingleIdentificationTypeTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.type } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceSingleIdentificationTypeTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleTypeType, invalidApiDocumentSingleTypeType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceSingleIdentificationTypeTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-identification-id-member - */ - describe('document-structure-resource-array-identification-id-member:', function documentStructureResourceArrayIdentificationIdMember() { - - const testingRuleName = 'document-structure-resource-array-identification-id-member'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayIdentificationIdMemberPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpressions = ruleset.rules[testingRuleName].given; - // debugDebug(`JSONPath Expression: ${jsonPathExpressions}`); - - const expectedExpressionPaths = [ - [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties } - ], - [ - // Left blank in purpose - ] - ]; - - jsonPathExpressions.forEach((jsonPathExpression, exprIndex) => { - - debugDebug(`JSONPath Expression [${exprIndex}]: ${jsonPathExpression}`); - - const expectedPaths = expectedExpressionPaths[exprIndex]; - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - // Check if the number of results matches the expected number for this expression - expect(result.length).to.equal(expectedPaths.length, `\x1b[31mExpected ${expectedPaths.length} elements to match in the OpenAPI Document for expression array index [${exprIndex}].\x1b[0m\n`); - - expectedPaths.forEach((path, pathIndex) => { - - // Additional checks for each path - debugInfo(`Element ${pathIndex + 1} found from JSONPath Expression array index [${exprIndex}]: \x1b[32m${JSON.stringify(result[pathIndex], null, 2)}`); - - // Check if each result matches the corresponding expected path - expect(result[pathIndex]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${pathIndex + 1}\x1b[0m`); - - }); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayIdentificationIdMemberFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayIdMember, invalidApiDocumentArrayIdMember); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayIdentificationIdMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-identification-id-type - */ - describe('document-structure-resource-array-identification-id-type:', function documentStructureResourceArrayIdentificationIdType() { - - const testingRuleName = 'document-structure-resource-array-identification-id-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayIdentificationIdTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpressions = ruleset.rules[testingRuleName].given; - // debugDebug(`JSONPath Expression: ${jsonPathExpressions}`); - - const expectedExpressionPaths = [ - [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.id } - ], - [ - // Left blank on purpose - ] - ]; - - jsonPathExpressions.forEach((jsonPathExpression, exprIndex) => { - - debugDebug(`JSONPath Expression [${exprIndex}]: ${jsonPathExpression}`); - - const expectedPaths = expectedExpressionPaths[exprIndex]; - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - // Check if the number of results matches the expected number for this expression - expect(result.length).to.equal(expectedPaths.length, `\x1b[31mExpected ${expectedPaths.length} elements to match in the OpenAPI Document for expression array index [${exprIndex}].\x1b[0m\n`); - - expectedPaths.forEach((path, pathIndex) => { - - // Additional checks for each path - debugInfo(`Element ${pathIndex + 1} found from JSONPath Expression array index [${exprIndex}]: \x1b[32m${JSON.stringify(result[pathIndex], null, 2)}`); - - // Check if each result matches the corresponding expected path - expect(result[pathIndex]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${pathIndex + 1}\x1b[0m`); - - }); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayIdentificationIdTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayIdType, invalidApiDocumentArrayIdType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayIdentificationIdTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-identification-type-member - */ - describe('document-structure-resource-array-identification-type-member:', function documentStructureResourceArrayIdentificationTypeMember() { - - const testingRuleName = 'document-structure-resource-array-identification-type-member'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayIdentificationTypeMemberPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayIdentificationTypeMemberFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayTypeMember, invalidApiDocumentArrayTypeMember); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayIdentificationTypeMemberPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-array-identification-type-type - */ - describe('document-structure-resource-array-identification-type-type:', function documentStructureResourceArrayIdentificationTypeType() { - - const testingRuleName = 'document-structure-resource-array-identification-type-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceArrayIdentificationTypeTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.type } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceArrayIdentificationTypeTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayTypeType, invalidApiDocumentArrayTypeType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceArrayIdentificationTypeTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-identifier-object.test.js b/test/jsonapi-document-structure-resource-identifier-object.test.js deleted file mode 100644 index 07d9882..0000000 --- a/test/jsonapi-document-structure-resource-identifier-object.test.js +++ /dev/null @@ -1,1076 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-document-structure-resource-identifier-object.js'; - -describe('jsonapi-document-structure-resource-identifier-object ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('relationships-data-object-explicit:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'myRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - } - } - } - } - } - } - } - } - }, - 'included': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'anotherRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - }, - 'meta': { - 'type': 'object' - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - }, - '/junk': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'myRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['relationships-data-object-explicit'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.myRelName.properties.data, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.properties.relationships.properties.anotherRelName.properties.data, - doc.paths['/junk'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.myRelName.properties.data - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "relationships-data-object-explicit" errors if relationships..data members do not meet min resource identifier object schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - type: - type: string - /junk: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - properties: - id: - type: string - type: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: array - items: - type: object - required: ["id", "type"] - properties: - id: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['relationships-data-object-composed']; - delete spectral.ruleset.rules['relationships-data-allowed-fields']; - spectral.run(badDocument) - .then((results) => { - - // using error start line numbers to keep from using looooong path statements. - // expect errors on lines 18,21,32,35,53,68,73 (7 in total) - - expect(results.length).to.equal(7, 'Error count should be 7'); - expect(results[0].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - expect(results[1].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - expect(results[2].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - expect(results[3].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - expect(results[4].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - expect(results[5].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - expect(results[6].code).to.equal('relationships-data-object-explicit', 'Incorrect error'); - - expect(results[0].range.start.line).to.equal(18, 'Wrong path'); - expect(results[1].range.start.line).to.equal(21, 'Wrong path'); - expect(results[2].range.start.line).to.equal(32, 'Wrong path'); - expect(results[3].range.start.line).to.equal(35, 'Wrong path'); - expect(results[4].range.start.line).to.equal(53, 'Wrong path'); - expect(results[5].range.start.line).to.equal(68, 'Wrong path'); - expect(results[6].range.start.line).to.equal(73, 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: array - items: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['relationships-data-object-composed']; - delete spectral.ruleset.rules['relationships-data-allowed-fields']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('relationships-data-object-composed:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'myRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'allOf': [ - { - 'type': 'object', - 'required': [ - 'id', - 'type' - ], - 'properties': { - 'id': { - 'type': 'string', - 'pattern': '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$', - 'example': '2357c52f-6c78-4747-8106-e185c08143aa' - }, - 'type': { - 'type': 'string' - } - } - }, - { - 'type': 'object', - 'properties': { - 'type': { - 'enum': [ - 'manufacturers' - ] - } - } - } - ] - } - } - } - } - } - } - }, - 'included': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'anotherRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'allOf': [ - { - 'type': 'object', - 'required': [ - 'id', - 'type' - ], - 'properties': { - 'id': { - 'type': 'string', - 'pattern': '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$', - 'example': '2357c52f-6c78-4747-8106-e185c08143aa' - }, - 'type': { - 'type': 'string' - } - } - }, - { - 'type': 'object', - 'properties': { - 'type': { - 'enum': [ - 'manufacturers' - ] - } - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - }, - '/junk': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'myRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'allOf': [ - { - 'type': 'object', - 'required': [ - 'id', - 'type' - ], - 'properties': { - 'id': { - 'type': 'string', - 'pattern': '^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[afA-F0-9]{4}-[a-fA-F0-9]{12}){1}$', - 'example': '2357c52f-6c78-4747-8106-e185c08143aa' - }, - 'type': { - 'type': 'string' - } - } - }, - { - 'type': 'object', - 'properties': { - 'type': { - 'enum': [ - 'manufacturers' - ] - } - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['relationships-data-object-composed'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.myRelName.properties.data.allOf, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.properties.relationships.properties.anotherRelName.properties.data.allOf, - doc.paths['/junk'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.myRelName.properties.data.allOf - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "relationships-data-object-composed" errors if relationships..data members do not meet min resource identifier object schema', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - allOf: - - type: object - required: ["id", "type"] - properties: - id: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - allOf: - - type: object - required: ["id", "type"] - properties: - type: - type: string - /junk: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - allOf: - - type: object - properties: - id: - type: string - type: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: array - items: - allOf: - - type: object - required: ["id", "type"] - properties: - id: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['relationships-data-object-explicit']; - delete spectral.ruleset.rules['relationships-data-allowed-fields']; - spectral.run(badDocument) - .then((results) => { - - // using error start line numbers to keep from using looooong path statements. - // expect errors on lines 19,34,56,74 (4 in total) - - expect(results.length).to.equal(4, 'Error count should be 4'); - expect(results[0].code).to.equal('relationships-data-object-composed', 'Incorrect error'); - expect(results[1].code).to.equal('relationships-data-object-composed', 'Incorrect error'); - expect(results[2].code).to.equal('relationships-data-object-composed', 'Incorrect error'); - expect(results[3].code).to.equal('relationships-data-object-composed', 'Incorrect error'); - - expect(results[0].range.start.line).to.equal(19, 'Wrong path'); - expect(results[1].range.start.line).to.equal(34, 'Wrong path'); - expect(results[2].range.start.line).to.equal(56, 'Wrong path'); - expect(results[3].range.start.line).to.equal(74, 'Wrong path'); - - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - allOf: - - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - meta: - type: object - - type: object - properties: - type: - enum: ["manufacturers"] - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['relationships-data-object-explicit']; - delete spectral.ruleset.rules['relationships-data-allowed-fields']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('relationships-data-allowed-fields:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'myRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - } - } - } - } - } - } - } - } - }, - 'included': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'anotherRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - }, - 'meta': { - 'type': 'object' - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - }, - '/junk': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'relationships': { - 'type': 'object', - 'properties': { - 'myRelName': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'array', - 'items': { - 'type': 'object', - 'required': ['id', 'type'], - 'properties': { - 'id': { - 'type': 'string' - }, - 'type': { - 'type': 'string' - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['relationships-data-allowed-fields'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.myRelName.properties.data.properties, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.properties.relationships.properties.anotherRelName.properties.data.properties, - doc.paths['/junk'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.myRelName.properties.data.items.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "relationships-data-allowed-fields" errors if object contains fields other than id, type, or meta ', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - badProp: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - meta2: - type: object - /junk: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - properties: - id: - type: string - type: - type: string - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: array - items: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['relationships-data-object-explicit']; - delete spectral.ruleset.rules['relationships-data-object-composed']; - spectral.run(badDocument) - .then((results) => { - - // using error start line numbers to keep from using looooong path statements. - // expect errors on lines 26, 44 (2 in total) - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('relationships-data-allowed-fields', 'Incorrect error'); - expect(results[1].code).to.equal('relationships-data-allowed-fields', 'Incorrect error'); - - expect(results[0].range.start.line).to.equal(26, 'Wrong path'); - expect(results[1].range.start.line).to.equal(44, 'Wrong path'); - - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - relationships: - type: object - properties: - myRelName: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - meta: - type: object - included: - type: array - items: - type: object - properties: - relationships: - type: object - properties: - data: - type: object - required: ["id", "type"] - properties: - id: - type: string - type: - type: string - enum: ["manufacturers"] - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['relationships-data-object-explicit']; - delete spectral.ruleset.rules['relationships-data-object-composed']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-resource-objects.test.js b/test/jsonapi-document-structure-resource-objects.test.js deleted file mode 100644 index 1756ae2..0000000 --- a/test/jsonapi-document-structure-resource-objects.test.js +++ /dev/null @@ -1,1566 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-document-structure-resource-objects.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo, debugDebug } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import invalidApiDocumentType from './docs/documentStructure/resourceObjects/invalidApiDocumentType.js'; -import invalidApiDocumentSingleStructure from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructure.js'; -import invalidApiDocumentSingleStructureLength from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleStructureLength.js'; -import invalidApiDocumentSingleTypeRequired from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeRequired.js'; -import invalidApiDocumentSingleIdRequired from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdRequired.js'; -import invalidApiDocumentSingleIdType from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleIdType.js'; -import invalidApiDocumentSingleTypeType from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleTypeType.js'; -import invalidApiDocumentSingleAttributesType from './docs/documentStructure/resourceObjects/invalidApiDocumentSingleAttributesType.js'; -import invalidApiDocumentArrayStructure from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructure.js'; -import invalidApiDocumentArrayStructureLength from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayStructureLength.js'; -import invalidApiDocumentArrayTypeRequired from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeRequired.js'; -import invalidApiDocumentArrayIdRequired from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdRequired.js'; -import invalidApiDocumentArrayIdType from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayIdType.js'; -import invalidApiDocumentArrayTypeType from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayTypeType.js'; -import invalidApiDocumentArrayAttributesType from './docs/documentStructure/resourceObjects/invalidApiDocumentArrayAttributesType.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API DocumentStructure.ResourceObjects ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-document-structure-resource-objects.js - * against various OpenAPI documents that are valid based on JSON: API standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset - * and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks - * if the provided error is an instance of AggregateError. If so, it iterates over each individual error within the - * aggregate and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility - * is particularly useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, - * resolving all $ref references found within. It supports nested structures and arrays, handles circular references, - * and removes resolved references from the components section if they are no longer needed. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ -describe('jsonapi-document-structure-resource-objects ruleset:', function documentStructureResourceObjectsSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - // Access the globally dereferenced document - dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - - }); - - /** - * Ruleset: document-structure-resource-objects-type - */ - describe('document-structure-resource-objects-type:', function documentStructureResourceObjectsType() { - - const testingRuleName = 'document-structure-resource-objects-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data }, - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentType, invalidApiDocumentType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 6; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-structure - */ - describe('document-structure-resource-objects-single-structure:', function documentStructureResourceObjectsSingleStructure() { - - const testingRuleName = 'document-structure-resource-objects-single-structure'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleStructurePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleStructureFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleStructure, invalidApiDocumentSingleStructure); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleStructurePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-structure-length - */ - describe('document-structure-resource-objects-single-structure-length:', function documentStructureResourceObjectsSingleStructureLength() { - - const testingRuleName = 'document-structure-resource-objects-single-structure-length'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleStructureLengthPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleStructureLengthFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleStructureLength, invalidApiDocumentSingleStructureLength); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleStructureLengthPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-type-required - */ - describe('document-structure-resource-objects-single-type-required:', function documentStructureResourceObjectsSingleTypeRequired() { - - const testingRuleName = 'document-structure-resource-objects-single-type-required'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleTypeRequiredPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleTypeRequiredFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleTypeRequired, invalidApiDocumentSingleTypeRequired); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleTypeRequiredPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-id-required - */ - describe('document-structure-resource-objects-single-id-required:', function documentStructureResourceObjectsSingleIdRequired() { - - const testingRuleName = 'document-structure-resource-objects-single-id-required'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleIdRequiredPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleIdRequiredFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleIdRequired, invalidApiDocumentSingleIdRequired); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleIdRequiredPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-id-type - */ - describe('document-structure-resource-objects-single-id-type:', function documentStructureResourceObjectsSingleIdType() { - - const testingRuleName = 'document-structure-resource-objects-single-id-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleIdTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.id } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleIdTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleIdType, invalidApiDocumentSingleIdType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 4; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleIdTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-type-type - */ - describe('document-structure-resource-objects-single-type-type:', function documentStructureResourceObjectsSingleTypeType() { - - const testingRuleName = 'document-structure-resource-objects-single-type-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleTypeTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.type }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.type } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleTypeTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleTypeType, invalidApiDocumentSingleTypeType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleTypeTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-single-attributes-type - */ - describe('document-structure-resource-objects-single-attributes-type:', function documentStructureResourceObjectsSingleAttributesType() { - - const testingRuleName = 'document-structure-resource-objects-single-attributes-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsSingleAttributesTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.requestBody.content['application/vnd.api+json'].schema.properties.data.properties.attributes }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.attributes } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsSingleAttributesTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleAttributesType, invalidApiDocumentSingleAttributesType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 5; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsSingleAttributesTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-structure - */ - describe('document-structure-resource-objects-array-structure:', function documentStructureResourceObjectsArrayStructure() { - - const testingRuleName = 'document-structure-resource-objects-array-structure'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayStructurePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayStructureFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayStructure, invalidApiDocumentArrayStructure); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayStructurePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-structure-length - */ - describe('document-structure-resource-objects-array-structure-length:', function documentStructureResourceObjectsArrayStructureLength() { - - const testingRuleName = 'document-structure-resource-objects-array-structure-length'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayStructureLengthPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayStructureLengthFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayStructureLength, invalidApiDocumentArrayStructureLength); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayStructureLengthPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-type-required - */ - describe('document-structure-resource-objects-array-type-required:', function documentStructureResourceObjectsArrayTypeRequired() { - - const testingRuleName = 'document-structure-resource-objects-array-type-required'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayTypeRequiredPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayTypeRequiredFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayTypeRequired, invalidApiDocumentArrayTypeRequired); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayTypeRequiredPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-id-required - */ - describe('document-structure-resource-objects-array-id-required:', function documentStructureResourceObjectsArrayIdRequired() { - - const testingRuleName = 'document-structure-resource-objects-array-id-required'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayIdRequiredPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayIdRequiredFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayIdRequired, invalidApiDocumentArrayIdRequired); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayIdRequiredPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-id-type - */ - describe('document-structure-resource-objects-array-id-type:', function documentStructureResourceObjectsArrayIdType() { - - const testingRuleName = 'document-structure-resource-objects-array-id-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayIdTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.id } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayIdTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayIdType, invalidApiDocumentArrayIdType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayIdTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-type-type - */ - describe('document-structure-resource-objects-array-type-type:', function documentStructureResourceObjectsArrayTypeType() { - - const testingRuleName = 'document-structure-resource-objects-array-type-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayTypeTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.type } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayTypeTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayTypeType, invalidApiDocumentArrayTypeType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayTypeTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: document-structure-resource-objects-array-attributes-type - */ - describe('document-structure-resource-objects-array-attributes-type:', function documentStructureResourceObjectsArrayAttributesType() { - - const testingRuleName = 'document-structure-resource-objects-array-attributes-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function documentStructureResourceObjectsArrayAttributesTypePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.attributes } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function documentStructureResourceObjectsArrayAttributesTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayAttributesType, invalidApiDocumentArrayAttributesType); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function documentStructureResourceObjectsArrayAttributesTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-document-structure-top-level.test.js b/test/jsonapi-document-structure-top-level.test.js deleted file mode 100644 index a30e0ec..0000000 --- a/test/jsonapi-document-structure-top-level.test.js +++ /dev/null @@ -1,757 +0,0 @@ -import { expect } from 'chai'; -import { JSONPath } from 'jsonpath-plus'; -import spectralCore from '@stoplight/spectral-core'; -const { Spectral, Document } = spectralCore; -import Parsers from '@stoplight/spectral-parsers'; - -// rules under test -import ruleset from '../rules/jsonapi-document-structure-top-level.js'; - -describe('jsonapi-document-structure-top-level ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('top-level-json-object:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object' - } - } - } - } - } - }, - '/junk': { - 'patch': { - 'requestBody': { - 'content': { - 'application/json': { - 'schema': { - 'type': 'string' - } - } - } - } - } - }, - '/things': { - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'string' - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['top-level-json-object'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema, - doc.paths['/things'].patch.requestBody.content['application/vnd.api+json'].schema - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "top-level-request-json-object" errors if using JSON:API and top level schema is NOT an object', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: string - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: string - /junk: - patch: - requestBody: - content: - application/json: - schema: - type: string - /things: - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - application/json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-properties']; - delete spectral.ruleset.rules['top-level-json-properties-included']; - delete spectral.ruleset.rules['top-level-json-properties-errors']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('top-level-json-object', 'Incorrect error'); - expect(results[1].code).to.equal('top-level-json-object', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/type', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/type', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - /junk: - patch: - requestBody: - content: - application/json: - schema: - type: string - /things: - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - application/json: - schema: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-properties']; - delete spectral.ruleset.rules['top-level-json-properties-included']; - delete spectral.ruleset.rules['top-level-json-properties-errors']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('top-level-json-properties:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object' - }, - 'links': { - 'type': 'object' - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object' - }, - 'links': { - 'type': 'object' - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['top-level-json-properties'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "top-level-json-properties" errors if top level schema properties are not allowed', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - links: - type: object - meta: - type: object - errors: - type: array - included: - type: array - jsonapi: - type: object - bar: - type: string - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - foo: - type: string - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-object']; - delete spectral.ruleset.rules['top-level-json-properties-included']; - delete spectral.ruleset.rules['top-level-json-properties-errors']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('top-level-json-properties', 'Incorrect error'); - expect(results[1].code).to.equal('top-level-json-properties', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/bar', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/foo', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - links: - type: object - meta: - type: object - errors: - type: array - included: - type: array - jsonapi: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-object']; - delete spectral.ruleset.rules['top-level-json-properties-included']; - delete spectral.ruleset.rules['top-level-json-properties-errors']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('top-level-json-properties-included:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object' - }, - 'links': { - 'type': 'object' - }, - 'included': { - 'type': 'array' - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object' - }, - 'links': { - 'type': 'object' - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['top-level-json-properties-included'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(1, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "top-level-json-properties-included" errors if included property exists w/o data property', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - links: - type: object - meta: - type: object - errors: - type: array - included: - type: array - jsonapi: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-object']; - delete spectral.ruleset.rules['top-level-json-properties']; - delete spectral.ruleset.rules['top-level-json-properties-errors']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('top-level-json-properties-included', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - links: - type: object - meta: - type: object - errors: - type: array - included: - type: array - jsonapi: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-object']; - delete spectral.ruleset.rules['top-level-json-properties']; - delete spectral.ruleset.rules['top-level-json-properties-errors']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - - describe('top-level-json-properties-errors:', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object' - }, - 'links': { - 'type': 'object' - }, - 'errors': { - 'type': 'array' - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object' - }, - 'links': { - 'type': 'object' - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = ruleset.rules['top-level-json-properties-errors'].given; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(1, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "top-level-json-properties-errors" errors if errors property exists w/ data property', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - links: - type: object - meta: - type: object - errors: - type: array - included: - type: array - jsonapi: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-object']; - delete spectral.ruleset.rules['top-level-json-properties']; - delete spectral.ruleset.rules['top-level-json-properties-included']; - spectral.run(badDocument) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('top-level-json-properties-errors', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data', 'Wrong path'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - `, Parsers.Yaml); - - spectral.setRuleset(ruleset); - delete spectral.ruleset.rules['top-level-json-object']; - delete spectral.ruleset.rules['top-level-json-properties']; - delete spectral.ruleset.rules['top-level-json-properties-included']; - spectral.run(cleanDocument) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }) - .catch((error) => { - - done(error); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-document-stucture-resource-object.test.js.old b/test/jsonapi-document-stucture-resource-object.test.js.old deleted file mode 100644 index 66f7dbb..0000000 --- a/test/jsonapi-document-stucture-resource-object.test.js.old +++ /dev/null @@ -1,1478 +0,0 @@ -'use strict'; - -const {join} = require('path'); -const {expect} = require('chai'); -const {Spectral, Document, Parsers} = require('@stoplight/spectral'); -const {JSONPath} = require('jsonpath-plus'); - -const RULESET_FILE = join(__dirname, '../rules/jsonapi-document-structure-resource-object.yaml'); - -describe('jsonapi-document-structure-resource-object ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - - describe('jsonapi-document-structure-resource-object-properties-object', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - }, - 'links': { - 'type': 'object' - }, - 'included': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': {} - }, - { - 'type': 'object', - 'properties': {} - } - - ] - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': {} - }, - { - 'type': 'object', - 'properties': {} - } - ] - } - }, - 'included': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'object')]^.properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.included.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource object properties" errors for object type', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - type: {} - id: {} - property1: {} - property2: {} - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - allOf: - - type: object - properties: {} - - type: object - properties: {} - included: - type: object - properties: - type: {} - id: {} - property1: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(3, 'Error count should be 3'); - expect(results[0].code).to.equal('resource-object-properties-object', 'Incorrect error'); - expect(results[1].code).to.equal('resource-object-properties-object', 'Incorrect error'); - expect(results[2].code).to.equal('resource-object-properties-object', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties/property1', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties/property2', 'Wrong path'); - expect(results[2].path.join('/')).to.equal('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/included/properties/property1', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - type: {} - id: {} - attributes: {} - relationships: {} - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - allOf: - - type: object - properties: {} - - type: object - properties: {} - included: - type: object - properties: - type: {} - id: {} - links: {} - meta: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-document-structure-resource-object-properties-array', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - }, - 'links': { - 'type': 'object' - }, - 'included': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': {} - }, - { - 'type': 'object', - 'properties': {} - } - ] - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': {} - }, - { - 'type': 'object', - 'properties': {} - } - ] - } - }, - 'included': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'array')]^..allOf.*.properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[0].properties, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[1].properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.data.items.allOf[0].properties, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.data.items.allOf[1].properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(4, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource object properties" errors for array type', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: {} - - included: - type: array - allOf: - - type: object - properties: - id: {} - type: {} - property1: {} - property2: {} - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - allOf: - - type: object - properties: - id: {} - type: {} - relationships: {} - - type: object - properties: - property1: {} - included: - type: object - properties: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(3, 'Error count should be 3'); - expect(results[0].code).to.equal('resource-object-properties-array', 'Incorrect error'); - expect(results[1].code).to.equal('resource-object-properties-array', 'Incorrect error'); - expect(results[2].code).to.equal('resource-object-properties-array', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/included/allOf/0/properties/property1', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/included/allOf/0/properties/property2', 'Wrong path'); - expect(results[2].path.join('/')).to.equal('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/data/allOf/1/properties/property1', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: {} - - included: - type: array - allOf: - - type: object - properties: - id: {} - type: {} - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - allOf: - - type: object - properties: - id: {} - type: {} - meta: {} - relationships: {} - - type: object - properties: - attributes: {} - included: - type: object - properties: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-document-structure-resource-object-properties-type-object', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': { - 'meta': {}, - 'attributes': {}, - 'relationships': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'array' - }, - 'included': { - 'type': 'object', - 'properties': { - 'links': {}, - 'meta': {} - } - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'object')]^.properties[?(@property === 'attributes' || @property === 'relationships' || @property === 'links' || @property === 'meta')]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.meta, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.attributes, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties.relationships, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.included.properties.links, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.included.properties.meta - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(5, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource object properties type" errors for object type', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - attributes: - type: string - meta: - type: string - relationships: - type: array - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - included: - type: object - properties: - links: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(4, 'Error count should be 4'); - expect(results[0].code).to.equal('resource-object-properties-type-object', 'Incorrect error'); - expect(results[1].code).to.equal('resource-object-properties-type-object', 'Incorrect error'); - expect(results[2].code).to.equal('resource-object-properties-type-object', 'Incorrect error'); - expect(results[3].code).to.equal('resource-object-properties-type-object', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties/attributes/type', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties/meta/type', 'Wrong path'); - expect(results[2].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties/relationships/type', 'Wrong path'); - expect(results[3].path.join('/')).to.equal('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/included/properties/links/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - attributes: - type: object - meta: - type: object - relationships: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - included: - type: object - properties: - links: - type: object - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-document-structure-resource-object-properties-type-array', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - }, - 'links': { - 'type': 'object' - }, - 'included': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'links': {}, - 'meta': {} - } - }, - { - 'type': 'object', - 'properties': { - 'relationships': {}, - 'anotherproperty': {} - } - } - ] - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'id': {}, - 'type': {}, - 'attributes': {} - } - }, - { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - ] - } - }, - 'included': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$.paths..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'array')]^..allOf.*.properties[?(@property === 'attributes' || @property === 'relationships' || @property === 'links' || @property === 'meta')]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[0].properties.links, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[0].properties.meta, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.items.allOf[1].properties.relationships, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.data.items.allOf[0].properties.attributes, - doc.paths['/stuff'].patch.requestBody.content['application/vnd.api+json'].schema.properties.data.items.allOf[1].properties.meta - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(5, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource object properties type" errors for array type', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - id: {} - type: {} - included: - type: array - allOf: - - type: object - properties: - links: - type: array - meta: - type: string - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - allOf: - - type: object - properties: - relationships: - type: array - - type: object - properties: - meta: - type: object - - type: object - properties: - id: {} - type: {} - included: - type: object - properties: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(3, 'Error count should be 3'); - expect(results[0].code).to.equal('resource-object-properties-type-array', 'Incorrect error'); - expect(results[1].code).to.equal('resource-object-properties-type-array', 'Incorrect error'); - expect(results[2].code).to.equal('resource-object-properties-type-array', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/included/allOf/0/properties/links/type', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/included/allOf/0/properties/meta/type', 'Wrong path'); - expect(results[2].path.join('/')).to.equal('paths//stuff/patch/requestBody/content/application/vnd.api+json/schema/properties/data/allOf/0/properties/relationships/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: {} - - included: - type: array - allOf: - - type: object - properties: - id: {} - type: {} - - type: object - properties: - meta: - type: object - links: - type: object - patch: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: array - allOf: - - type: object - properties: - id: {} - type: {} - meta: - type: object - relationships: - type: object - - type: object - properties: - attributes: - type: object - included: - type: object - properties: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-document-structure-resource-object-properties-included-object', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - }, - 'links': { - 'type': 'object' - }, - 'included': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - } - } - }, - 'post': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - }, - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - }, - 'links': { - 'type': 'object' - }, - 'included': { - 'type': 'array', - 'items': {} - } - } - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$.paths.*.[?(@property === 'requestBody' && @parentProperty !== 'post' || @property === 'responses')]..content[?(@property === 'application/vnd.api+json')].schema.properties[?(@property === 'data' || @property === 'included')][?(@property === 'type' && @ === 'object')]^.properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.data.properties, - doc.paths['/stuff'].get.responses[200].content['application/vnd.api+json'].schema.properties.included.properties, - doc.paths['/stuff'].post.responses[200].content['application/vnd.api+json'].schema.properties.data.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(3, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource object properties included" errors for object type', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - type: {} - included: - type: array - allOf: - - type: object - properties: {} - post: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: object - properties: - type: {} - responses: - '200': - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: object - properties: - type: {} - included: - type: object - properties: - id: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(3, 'Error count should be 3'); - expect(results[0].code).to.equal('resource-object-properties-included-object', 'Incorrect error'); - expect(results[1].code).to.equal('resource-object-properties-included-object', 'Incorrect error'); - expect(results[2].code).to.equal('resource-object-properties-included-object', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/200/content/application/vnd.api+json/schema/properties/data/properties', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/post/responses/200/content/application/vnd.api+json/schema/properties/data/properties', 'Wrong path'); - expect(results[2].path.join('/')).to.equal('paths//stuff/post/responses/200/content/application/vnd.api+json/schema/properties/included/properties', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: - data: - type: object - properties: - id: {} - type: {} - - included: - type: array - allOf: - - type: object - properties: {} - post: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: object - properties: - type: {} - responses: - '200': - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: object - properties: - id: {} - type: {} - included: - type: object - properties: - type: {} - id: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-array']; - delete spectral.rules['resource-object-id-exception']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-document-structure-resource-object-id-exception', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - }, - 'post': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'data': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - }, - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': {} - } - } - } - } - } - } - } - } - }; - - const jsonPathExpression = "$.paths..[?(@property === 'post')][?(@property === 'requestBody')]..schema.properties[data][?(@property === 'type' && @ === 'object')]^.properties"; - const expectedPaths = [ - doc.paths['/stuff'].post.requestBody.content['application/vnd.api+json'].schema.properties.data.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(1, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "resource object id exception" errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: {} - - post: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: object - properties: - property1: {} - responses: - '200': - content: - application/vnd.api+json: - schema: - type: array - properties: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('resource-object-id-exception', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/post/requestBody/content/application/vnd.api+json/schema/properties/data/properties', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should pass with NO errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '200': - content: - application/vnd.api+json: - schema: - type: object - properties: {} - - post: - requestBody: - content: - application/vnd.api+json: - schema: - type: array - properties: - data: - type: object - properties: - type: {} - property1: {} - property2: {} - responses: - '200': - content: - application/vnd.api+json: - schema: - type: array - properties: {} - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['resource-object-properties-object']; - delete spectral.rules['resource-object-properties-array']; - delete spectral.rules['resource-object-properties-type-object']; - delete spectral.rules['resource-object-properties-type-array']; - delete spectral.rules['resource-object-properties-included-object']; - delete spectral.rules['resource-object-properties-included-array']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-errors-error-object.test.js.old b/test/jsonapi-errors-error-object.test.js.old deleted file mode 100644 index a763383..0000000 --- a/test/jsonapi-errors-error-object.test.js.old +++ /dev/null @@ -1,1588 +0,0 @@ -'use strict'; - -const {join} = require('path'); -const {expect} = require('chai'); -const {Spectral, Document, Parsers} = require('@stoplight/spectral'); -const {JSONPath} = require('jsonpath-plus'); - -const RULESET_FILE = join(__dirname, '../rules/jsonapi-errors-error-object.yaml'); - -describe('jsonapi-errors-error-object ruleset:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - - }); - - describe('jsonapi-errors-error-object-type', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': {} - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(1, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "error-object-type" error', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('error-object-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no type errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - //remove rule(s) we aren't testing - .then(() => { - - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-properties', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'description': 'JSON:API Error Object', - 'properties': { - 'id': { - 'type': 'string' - } - } - }, - { - 'type': 'object', - 'properties': { - 'status': { - 'type': 'string' - } - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return "error-object-property" errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - description: 'Unauthorized: Invalid or Expired Authentication' - properties: - data: - type: object - - type: object - properties: - id: - type: string - included: - type: array - code: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('error-object-properties', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/data', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/1/properties/included', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no property errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - description: 'Unauthorized: Invalid or Expired Authentication' - properties: - status: - type: string - title: - type: string - - type: object - properties: - id: - type: string - links: - type: object - code: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-members-type-object', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '302': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'id': {}, - 'links': {} - } - }, - { - 'type': 'object', - 'properties': { - 'status': {}, - 'links': {}, - 'meta': {}, - 'source': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[?(@property === 'links' || @property === 'meta' || @property === 'source')]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.links, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.links, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.meta, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.source - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(4, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return member type errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - links: - type: object - meta: - type: array - - type: object - properties: - source: - type: string - links: - type: string - code: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(3, 'Error count should be 3'); - expect(results[0].code).to.equal('error-object-members-type-object', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/meta/type', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/1/properties/source/type', 'Wrong path'); - expect(results[2].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/1/properties/links/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no type errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - links: - type: object - - type: object - properties: - source: - type: object - links: - type: object - code: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-members-type-string', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '202': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'id': {}, - 'links': {}, - 'status': {}, - 'source': {}, - 'code': {} - } - }, - { - 'type': 'object', - 'properties': { - 'links': {}, - 'meta': {}, - 'title': {}, - 'detail': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[?(@property === 'status' || @property === 'code' || @property === 'title' || @property === 'detail')]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.status, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.code, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.title, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.detail - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(4, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return member type errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: object - code: - type: string - links: - type: object - - type: object - properties: - detail: - type: string - title: - type: object - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('error-object-members-type-string', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/status/type', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/1/properties/title/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no type errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - code: - type: string - links: - type: object - - type: object - properties: - detail: - type: string - title: - type: string - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-links-properties', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'id': {}, - 'links': { - 'properties': {} - } - } - }, - { - 'type': 'object', - 'properties': { - 'links': { - 'properties': {} - }, - 'detail': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[links].properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.links.properties, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.links.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return link property errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - links: - type: object - properties: - id: - type: string - - type: object - properties: - links: - type: object - properties: - meta: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('error-object-links-properties', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/links/properties', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/1/properties/links/properties', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no property errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - links: - type: object - properties: - about: - type: object - meta: - type: object - - type: object - properties: - links: - type: object - properties: - about: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-source-properties', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '201': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'id': {}, - 'source': { - 'properties': {} - } - } - }, - { - 'type': 'object', - 'properties': { - 'source': { - 'properties': {} - }, - 'detail': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[source].properties"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.source.properties, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.source.properties - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return source property errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - source: - type: object - properties: - id: - type: string - parameter: - type: string - - type: object - properties: - source: - type: object - properties: - parameter: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('error-object-source-properties', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/source/properties/id', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no property errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - source: - type: object - properties: - pointer: - type: object - parameter: - type: string - - type: object - properties: - source: - type: object - properties: - parameter: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-source-parameter-type']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-source-parameter-type', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'source': { - 'properties': { - 'pointer': {}, - 'parameter': {} - } - } - } - }, - { - 'type': 'object', - 'properties': { - 'source': { - 'properties': { - 'parameter': {} - } - }, - 'detail': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[source].properties[parameter]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.source.properties.parameter, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.source.properties.parameter - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return parameter property errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: object - - type: object - properties: - source: - type: object - properties: - pointer: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(1, 'Error count should be 1'); - expect(results[0].code).to.equal('error-object-source-parameter-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/source/properties/parameter/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no property errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - source: - type: object - properties: - pointer: - type: object - parameter: - type: string - - type: object - properties: - source: - type: object - properties: - parameter: - type: string - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-pointer-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - - describe('jsonapi-errors-error-object-source-pointer-type', function () { - - it('the json path expression should find the correct paths from the given document', function (done) { - - const doc = { - 'openapi': '3.0.2', - 'paths': { - '/stuff': { - 'get': { - 'responses': { - '200': {}, - '401': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'errors': { - 'type': 'array', - 'items': { - 'allOf': [ - { - 'type': 'object', - 'properties': { - 'source': { - 'properties': { - 'pointer': {}, - 'parameter': {} - } - } - } - }, - { - 'type': 'object', - 'properties': { - 'source': { - 'properties': { - 'pointer': {} - } - }, - 'detail': {} - } - } - ] - } - } - } - } - } - } - } - } - } - } - } - }; - const jsonPathExpression = "$.paths..responses[?(@property >= '400' && @property <= '599')].content[application/vnd.api+json].schema.properties[errors]..allOf.*.properties[source].properties[pointer]"; - const expectedPaths = [ - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[0].properties.source.properties.pointer, - doc.paths['/stuff'].get.responses[401].content['application/vnd.api+json'].schema.properties.errors.items.allOf[1].properties.source.properties.pointer - ]; - - const results = JSONPath(jsonPathExpression, doc); - - expect(results.length).to.equal(2, 'Wrong number of results.'); - expect(results).to.deep.equal(expectedPaths, 'Wrong paths'); - done(); - - }); - - it('the rule should return parameter property errors', function (done) { - - const badDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - source: - type: object - properties: - pointer: - type: object - parameter: - type: string - - type: object - properties: - source: - type: object - properties: - pointer: - type: string - '403': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - source: - type: object - properties: - pointer: - type: string - - type: object - properties: - source: - type: object - properties: - pointer: - type: object - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - - }) - .then(() => { - - return spectral.run(badDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(2, 'Error count should be 2'); - expect(results[0].code).to.equal('error-object-source-pointer-type', 'Incorrect error'); - expect(results[1].code).to.equal('error-object-source-pointer-type', 'Incorrect error'); - expect(results[0].path.join('/')).to.equal('paths//stuff/get/responses/401/content/application/vnd.api+json/schema/properties/errors/items/allOf/0/properties/source/properties/pointer/type', 'Wrong path'); - expect(results[1].path.join('/')).to.equal('paths//stuff/get/responses/403/content/application/vnd.api+json/schema/properties/errors/items/allOf/1/properties/source/properties/pointer/type', 'Wrong path'); - done(); - - }); - - }); - - it('the rule should return no property errors', function (done) { - - const cleanDocument = new Document(` - openapi: 3.0.2 - paths: - /stuff: - get: - responses: - '401': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - status: - type: string - source: - type: object - properties: - pointer: - type: string - parameter: - type: string - - type: object - properties: - source: - type: object - properties: - pointer: - type: array - '403': - content: - application/vnd.api+json: - schema: - type: object - properties: - errors: - type: array - items: - allOf: - - type: object - properties: - source: - type: object - properties: - pointer: - type: array - `, Parsers.Yaml); - - spectral.loadRuleset(RULESET_FILE) - .then(() => { - - delete spectral.rules['error-object-type']; - delete spectral.rules['error-object-properties']; - delete spectral.rules['error-object-members-type-object']; - delete spectral.rules['error-object-members-type-string']; - delete spectral.rules['error-object-links-properties']; - delete spectral.rules['error-object-source-properties']; - delete spectral.rules['error-object-source-parameter-type']; - - }) - .then(() => { - - return spectral.run(cleanDocument); - - }) - .then((results) => { - - expect(results.length).to.equal(0, 'Error(s) found'); - done(); - - }); - - }); - - }); - -}); diff --git a/test/jsonapi-errors-error-objects.test.js b/test/jsonapi-errors-error-objects.test.js deleted file mode 100644 index 3b9f539..0000000 --- a/test/jsonapi-errors-error-objects.test.js +++ /dev/null @@ -1,1485 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-errors-error-object.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import validApiDocument from './docs/errors/errorObjects/validApiDocument.js'; -import invalidApiDocumentArrayStructure from './docs/errors/errorObjects/invalidApiDocumentArrayStructure.js'; -import invalidApiDocumentObjectStructure from './docs/errors/errorObjects/invalidApiDocumentObjectStructure.js'; -import invalidApiDocumentItemsIdType from './docs/errors/errorObjects/invalidApiDocumentItemsIdType.js'; -import invalidApiDocumentObjectStructureLength from './docs/errors/errorObjects/invalidApiDocumentObjectStructureLength.js'; -import invalidApiDocumentItemsLinksMembers from './docs/errors/errorObjects/invalidApiDocumentItemsLinksMembers.js'; -import invalidApiDocumentItemsLinksStructureLength from './docs/errors/errorObjects/invalidApiDocumentItemsLinksStructureLength.js'; -import invalidApiDocumentItemsStatusType from './docs/errors/errorObjects/invalidApiDocumentItemsStatusType.js'; -import invalidApiDocumentItemsCodeType from './docs/errors/errorObjects/invalidApiDocumentItemsCodeType.js'; -import invalidApiDocumentItemsTitleType from './docs/errors/errorObjects/invalidApiDocumentItemsTitleType.js'; -import invalidApiDocumentItemsDetailType from './docs/errors/errorObjects/invalidApiDocumentItemsDetailType.js'; -import invalidApiDocumentItemsSourceType from './docs/errors/errorObjects/invalidApiDocumentItemsSourceType.js'; -import invalidApiDocumentItemsSourceMembers from './docs/errors/errorObjects/invalidApiDocumentItemsSourceMembers.js'; -import invalidApiDocumentItemsSourcePointerType from './docs/errors/errorObjects/invalidApiDocumentItemsSourcePointerType.js'; -import invalidApiDocumentItemsSourceParameterType from './docs/errors/errorObjects/invalidApiDocumentItemsSourceParameterType.js'; -import invalidApiDocumentItemsSourceStructureLength from './docs/errors/errorObjects/invalidApiDocumentItemsSourceStructureLength.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API Errors.ErrorObjects ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-errors-error-object.js - * against various OpenAPI documents that are valid based on JSON: API standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks if the provided error is an instance of AggregateError. If so, it iterates over each individual error within the aggregate and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility is particularly useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, resolving all $ref references found within. It supports nested structures and arrays, handles circular references, and removes resolved references from the components section if they are no longer needed. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ -describe('jsonapi-errors-error-objects ruleset:', function errorsErrorObjectsSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - dereferenceValidApiDocument = resolveRef(validApiDocument, validApiDocument); - - }); - - /** - * Ruleset: errors-error-objects-array-structure - */ - describe('errors-error-objects-array-structure:', function errorsErrorObjectsArrayStructure() { - - const testingRuleName = 'errors-error-objects-array-structure'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsArrayStructurePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsArrayStructureFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayStructure, invalidApiDocumentArrayStructure); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsArrayStructurePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-object-structure - */ - describe('errors-error-objects-object-structure:', function errorsErrorObjectsObjectStructure() { - - const testingRuleName = 'errors-error-objects-object-structure'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsObjectStructurePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsObjectStructureFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentObjectStructure, invalidApiDocumentObjectStructure); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 24; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsObjectStructurePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-object-structure-length - */ - describe('errors-error-objects-object-structure-length:', function errorsErrorObjectsObjectStructureLength() { - - const testingRuleName = 'errors-error-objects-object-structure-length'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsObjectStructureLengthPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsObjectStructureLengthFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentObjectStructureLength, invalidApiDocumentObjectStructureLength); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsObjectStructureLengthPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-id-type - */ - describe('errors-error-objects-items-id-type:', function errorsErrorObjectsItemsIdType() { - - const testingRuleName = 'errors-error-objects-items-id-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsIdTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.id }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.id } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsIdTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsIdType, invalidApiDocumentItemsIdType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsIdTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-links-members - */ - describe('errors-error-objects-items-links-members:', function errorsErrorObjectsItemsLinksMembers() { - - const testingRuleName = 'errors-error-objects-items-links-members'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsLinksMembersPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.links.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.links.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.links.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsLinksMembersFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsLinksMembers, invalidApiDocumentItemsLinksMembers); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsLinksMembersPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-links-structure-length - */ - describe('errors-error-objects-items-links-structure-length:', function errorsErrorObjectsItemsLinksStructureLength() { - - const testingRuleName = 'errors-error-objects-items-links-structure-length'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsLinksStructureLengthPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.links }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.links }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.links } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsLinksStructureLengthFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsLinksStructureLength, invalidApiDocumentItemsLinksStructureLength); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsLinksStructureLengthPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-status-type - */ - describe('errors-error-objects-items-status-type:', function errorsErrorObjectsItemsStatusType() { - - const testingRuleName = 'errors-error-objects-items-status-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsStatusTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.status }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.status }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.status } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsStatusTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsStatusType, invalidApiDocumentItemsStatusType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsStatusTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-code-type - */ - describe('errors-error-objects-items-code-type:', function errorsErrorObjectsItemsCodeType() { - - const testingRuleName = 'errors-error-objects-items-code-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsCodeTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.code }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.code }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.code } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsCodeTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsCodeType, invalidApiDocumentItemsCodeType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsCodeTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-title-type - */ - describe('errors-error-objects-items-title-type:', function errorsErrorObjectsItemsTitleType() { - - const testingRuleName = 'errors-error-objects-items-title-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsTitleTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.title }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.title }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.title } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsTitleTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsTitleType, invalidApiDocumentItemsTitleType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsTitleTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-detail-type - */ - describe('errors-error-objects-items-detail-type:', function errorsErrorObjectsItemsDetailType() { - - const testingRuleName = 'errors-error-objects-items-detail-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsDetailTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.detail }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.detail }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.detail } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsDetailTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsDetailType, invalidApiDocumentItemsDetailType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsDetailTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-source-type - */ - describe('errors-error-objects-items-source-type:', function errorsErrorObjectsItemsSourceType() { - - const testingRuleName = 'errors-error-objects-items-source-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsSourceTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsSourceTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsSourceType, invalidApiDocumentItemsSourceType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsSourceTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-source-members - */ - describe('errors-error-objects-items-source-members:', function errorsErrorObjectsItemsSourceMembers() { - - const testingRuleName = 'errors-error-objects-items-source-members'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsSourceMembersPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsSourceMembersFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsSourceMembers, invalidApiDocumentItemsSourceMembers); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsSourceMembersPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-source-pointer-type - */ - describe('errors-error-objects-items-source-pointer-type:', function errorsErrorObjectsItemsSourcePointerType() { - - const testingRuleName = 'errors-error-objects-items-source-pointer-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsSourcePointerTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties.pointer }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties.pointer }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties.pointer } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsSourcePointerTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsSourcePointerType, invalidApiDocumentItemsSourcePointerType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsSourcePointerTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-source-parameter-type - */ - describe('errors-error-objects-items-source-parameter-type:', function errorsErrorObjectsItemsSourceParameterType() { - - const testingRuleName = 'errors-error-objects-items-source-parameter-type'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsSourceParameterTypePath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties.parameter }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties.parameter }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source.properties.parameter } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsSourceParameterTypeFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsSourceParameterType, invalidApiDocumentItemsSourceParameterType); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsSourceParameterTypePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-error-objects-items-source-structure-length - */ - describe('errors-error-objects-items-source-structure-length:', function errorsErrorObjectsItemsSourceStructureLength() { - - const testingRuleName = 'errors-error-objects-items-source-structure-length'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsErrorObjectsItemsSourceStructureLengthPath() { - - try { - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, '\x1b[31mThe wrong JSONPath Expression was provided.\x1b[0m'); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsErrorObjectsItemsSourceStructureLengthFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentItemsSourceStructureLength, invalidApiDocumentItemsSourceStructureLength); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(` \x1b[31m- ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '${testingRuleName}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsErrorObjectsItemsSourceStructureLengthPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-errors-processing-errors.test.js b/test/jsonapi-errors-processing-errors.test.js deleted file mode 100644 index b748313..0000000 --- a/test/jsonapi-errors-processing-errors.test.js +++ /dev/null @@ -1,267 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-errors-processing-errors.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo, debugDebug } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import invalidApiDocumentArrayMaxItems from './docs/errors/processingErrors/invalidApiDocumentArrayMaxItems.js'; -import invalidApiDocumentArrayMaxItemsValue from './docs/errors/processingErrors/invalidApiDocumentArrayMaxItemsValue.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API Errors.ProcessingErrors ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-errors-processing-errors.js - * against various OpenAPI documents that are valid based on JSON: API v1.0 standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset - * and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks if - * the provided error is an instance of AggregateError. If so, it iterates over each individual error within the aggregate - * and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility is particularly - * useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, - * resolving all $ref references found within. It supports nested structures and arrays, handles circular references, and - * keeps resolved references from the components section for when they are needed at a later time. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ -describe('jsonapi-errors-processing-errors ruleset:', function errorsProcessingErrorsSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - // Access the globally dereferenced document - dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - - }); - - /** - * Ruleset: errors-processing-errors-array-max-items - */ - describe('errors-processing-errors-array-max-items:', function errorsProcessingErrorsArrayMaxItems() { - - const testingRuleName = 'errors-processing-errors-array-max-items'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsProcessingErrorsArrayMaxItemsPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].delete.responses['404'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].delete.responses['500'].content['application/vnd.api+json'].schema.properties.errors } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsProcessingErrorsArrayMaxItemsFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayMaxItems, invalidApiDocumentArrayMaxItems); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 10; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsProcessingErrorsArrayMaxItemsPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: errors-processing-errors-array-max-items-value - */ - describe('errors-processing-errors-array-max-items-value:', function errorsProcessingErrorsArrayMaxItemsValue() { - - const testingRuleName = 'errors-processing-errors-array-max-items-value'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function errorsProcessingErrorsArrayMaxItemsValuePath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['404'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['400'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['500'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].delete.responses['404'].content['application/vnd.api+json'].schema.properties.errors }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].delete.responses['500'].content['application/vnd.api+json'].schema.properties.errors } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function errorsProcessingErrorsArrayMaxItemsValueFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayMaxItemsValue, invalidApiDocumentArrayMaxItemsValue); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 10; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function errorsProcessingErrorsArrayMaxItemsValuePassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-fetching-data-fetching-resources.test.js b/test/jsonapi-fetching-data-fetching-resources.test.js deleted file mode 100644 index 79377af..0000000 --- a/test/jsonapi-fetching-data-fetching-resources.test.js +++ /dev/null @@ -1,551 +0,0 @@ -/* eslint-env mocha */ -import { JSONPath } from 'jsonpath-plus'; - -// Rules to test -import ruleset from '../rules/jsonapi-fetching-data-fetching-resources.js'; - -// Helper Functions -import { resolveRef } from './utils/refResolver.js'; -import { handleSpectralResults } from './utils/handleSpectralResults.js'; -import { processErrors } from './utils/processErrors.js'; -import { debugLog, debugError, debugInfo, debugDebug } from './utils/debugUtils.js'; -import { setupSpectralBeforeEach } from './utils/setupSpectralBeforeEach.js'; - -// OpenAPI Documents -import invalidApiDocumentTopLevelLinks from './docs/fetchingData/fetchingResources/invalidApiDocumentTopLevelLinks.js'; -import invalidApiDocumentSingleLevelSelfLink from './docs/fetchingData/fetchingResources/invalidApiDocumentSingleLevelSelfLink.js'; -import invalidApiDocumentSingleRelationshipLevelRelatedLink from './docs/fetchingData/fetchingResources/invalidApiDocumentSingleRelationshipLevelRelatedLink.js'; -import invalidApiDocumentArrayLevelSelfLink from './docs/fetchingData/fetchingResources/invalidApiDocumentArrayLevelSelfLink.js'; -import invalidApiDocumentArrayRelationshipLevelRelatedLink from './docs/fetchingData/fetchingResources/invalidApiDocumentArrayRelationshipLevelRelatedLink.js'; - -/** - * @fileoverview This test suite validates the behavior of the JSON: API FetchingData.FetchingResources ruleset - * when given OpenAPI documents. It tests the different rules defined in jsonapi-fetching-data-fetching-resources.js - * against various OpenAPI documents that are valid based on JSON: API v1.0 standards - * - * The tests leverage several helper methods: - * - `setupSpectralBeforeEach`: Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset - * and enabling specific rules. - * - `handleSpectralResults`: Filters and handles the results of the spectral run. - * - `processErrors`: Processes and logs errors, specifically handling AggregateErrors separately. This function checks if - * the provided error is an instance of AggregateError. If so, it iterates over each individual error within the aggregate - * and logs them separately. For all other types of errors, it logs them as unexpected errors. This utility is particularly - * useful for handling and debugging multiple errors that can occur during Spectral setup or execution. - * - `resolveRef`: Recursively resolves $ref references in an OpenAPI document. This function handles objects and arrays, - * resolving all $ref references found within. It supports nested structures and arrays, handles circular references, and - * keeps resolved references from the components section for when they are needed at a later time. - * - * The suite uses Mocha for test execution and Chai for assertions. - * - * Each ruleset has three test cases that focuses on the following: - * - Validate the JSONPath Expression for that rule - * - Generate a negative case scenario for that rule - * - Generate a positive case scenario for that rule - */ - -describe('jsonapi-fetching-data-fetching-resources ruleset:', function fetchingDataFetchingResourcesSuite() { - - let dereferenceValidApiDocument; - - before(function () { - - // Access the globally dereferenced document - dereferenceValidApiDocument = global.dereferencedValidOpenApiDocument; - - }); - - /** - * Ruleset: fetching-data-fetching-resources-top-level-links - */ - describe('fetching-data-fetching-resources-top-level-links:', function fetchingDataFetchingResourcesTopLevelLinks() { - - const testingRuleName = 'fetching-data-fetching-resources-top-level-links'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function fetchingDataFetchingResourcesTopLevelLinksPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.links.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function fetchingDataFetchingResourcesTopLevelLinksFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentTopLevelLinks, invalidApiDocumentTopLevelLinks); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function fetchingDataFetchingResourcesTopLevelLinksPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: fetching-data-fetching-resources-single-level-self-link - */ - describe('fetching-data-fetching-resources-single-level-self-link:', function fetchingDataFetchingResourcesSingleLevelSelfLink() { - - const testingRuleName = 'fetching-data-fetching-resources-single-level-self-link'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function fetchingDataFetchingResourcesSingleLevelSelfLinkPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.links.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.links.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.links.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function fetchingDataFetchingResourcesSingleLevelSelfLinkFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleLevelSelfLink, invalidApiDocumentSingleLevelSelfLink); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function fetchingDataFetchingResourcesSingleLevelSelfLinkPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: fetching-data-fetching-resources-single-relationship-level-related-link - */ - describe('fetching-data-fetching-resources-single-relationship-level-related-link:', function fetchingDataFetchingResourcesSingleRelationshipLevelRelatedLink() { - - const testingRuleName = 'fetching-data-fetching-resources-single-relationship-level-related-link'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function fetchingDataFetchingResourcesSingleRelationshipLevelRelatedLinkPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].post.responses['201'].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.posts.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.posts.properties }, - { expected: dereferenceValidApiDocument.paths['/users/{userId}'].put.responses['200'].content['application/vnd.api+json'].schema.properties.data.properties.relationships.properties.posts.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function fetchingDataFetchingResourcesSingleRelationshipLevelRelatedLinkFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentSingleRelationshipLevelRelatedLink, invalidApiDocumentSingleRelationshipLevelRelatedLink); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 3; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function fetchingDataFetchingResourcesSingleRelationshipLevelRelatedLinkPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: fetching-data-fetching-resources-array-level-self-link - */ - describe('fetching-data-fetching-resources-array-level-self-link:', function fetchingDataFetchingResourcesArrayLevelSelfLink() { - - const testingRuleName = 'fetching-data-fetching-resources-array-level-self-link'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function fetchingDataFetchingResourcesArrayLevelSelfLinkPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.links.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function fetchingDataFetchingResourcesArrayLevelSelfLinkFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayLevelSelfLink, invalidApiDocumentArrayLevelSelfLink); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function fetchingDataFetchingResourcesArrayLevelSelfLinkPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - - /** - * Ruleset: fetching-data-fetching-resources-array-relationship-level-related-link - */ - describe('fetching-data-fetching-resources-array-relationship-level-related-link:', function fetchingDataFetchingResourcesArrayRelationshipLevelRelatedLink() { - - const testingRuleName = 'fetching-data-fetching-resources-array-relationship-level-related-link'; - - beforeEach(setupSpectralBeforeEach(ruleset, [testingRuleName])); - - it('the json path expression should find the correct paths from the given document', function fetchingDataFetchingResourcesArrayRelationshipLevelRelatedLinkPath() { - - try { - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferenceValidApiDocument, null, 2)}`); - - const jsonPathExpression = ruleset.rules[testingRuleName].given; - debugDebug(`JSONPath Expression: ${jsonPathExpression}`); - const expectedExpressionPaths = [ - { expected: dereferenceValidApiDocument.paths['/users'].get.responses['200'].content['application/vnd.api+json'].schema.properties.data.items.properties.relationships.properties.posts.properties } - ]; - - expectedExpressionPaths.forEach((path, index) => { - - const result = JSONPath({ path: jsonPathExpression, - json: dereferenceValidApiDocument }); - - debugInfo(`Element ${index + 1} found from JSONPath Expression: \x1b[32m${JSON.stringify(result[index], null, 2)}`); - - // Check if the number of results matches the expected number - expect(result.length).to.equal(expectedExpressionPaths.length, `\x1b[31mExpected ${expectedExpressionPaths.length} elements to match in the OpenAPI Document.\x1b[0m\n`); - - // Check if each result matches the corresponding expected path - expect(result[index]).to.deep.equal(path.expected, `\x1b[31mThe wrong JSONPath Expression was provided in expected path: ${index + 1}\x1b[0m`); - - }); - - } catch (error) { - - processErrors(error); - - } - - }); - - it(`the rule should return "${testingRuleName}" errors, if ${ruleset.rules[testingRuleName].description} is false`, async function fetchingDataFetchingResourcesArrayRelationshipLevelRelatedLinkFailure() { - - try { - - const dereferencedOpenApiDocument = resolveRef(invalidApiDocumentArrayRelationshipLevelRelatedLink, invalidApiDocumentArrayRelationshipLevelRelatedLink); - - // debugDebug(`Dereferenced Document: ${JSON.stringify(dereferencedOpenApiDocument,null,2)}`); - - const relevantResults = await handleSpectralResults(this.spectral, dereferencedOpenApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - relevantResults.forEach((result) => { - - debugError(`\x1b[32mResults for '\x1b[33m${testingRuleName}\x1b[32m':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - }); - - const confirmedErrors = 1; - const errorMessage = `\x1b[31mError count should be ${confirmedErrors}.\x1b[0m`; - - expect(relevantResults.length).to.equal(confirmedErrors, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - it('the rule should pass with NO errors', async function fetchingDataFetchingResourcesArrayRelationshipLevelRelatedLinkPassing() { - - try { - - const relevantResults = await handleSpectralResults(this.spectral, dereferenceValidApiDocument, testingRuleName); - - debugLog(` Confirmed Errors:`); - debugLog(`\x1b[33m - ${relevantResults.length}\x1b[0m\n`); - - const errorMessage = `\x1b[31mError count should be 0, ${ruleset.rules[testingRuleName].description}\x1b[0m`; - expect(relevantResults.length).to.equal(0, errorMessage); - - } catch (error) { - - processErrors(error); - - } - - }); - - }); - -}); diff --git a/test/jsonapi-query-parameters.test.js.old b/test/jsonapi-query-parameters.test.js.old deleted file mode 100644 index 2d40715..0000000 --- a/test/jsonapi-query-parameters.test.js.old +++ /dev/null @@ -1,514 +0,0 @@ -import { expect } from 'chai'; -import spectralCore from '@stoplight/spectral-core'; -import { DiagnosticSeverity } from '@stoplight/types'; - -const { Spectral } = spectralCore; - -// rules under test -import ruleset from '../rules/jsonapi-query-parameters.js'; - -describe('jsonapi-query-parameters ruleset:', function () { - - let spectral; - - // Common setup for all test cases - beforeEach(function () { - - spectral = new Spectral(); - spectral.setRuleset(ruleset); - - }); - - // see test/assets/example-jsonapi-oas.yaml see filter and fields - // describe('get-filter-query-parameters:', function () { - - // Test cases for valid query fields/parameters - it('should pass with no errors for valid query fields/parameters', async function () { - - const validDocument = { - 'openapi': '3.0.2', - 'paths': { - '/myResources': { - 'get': { - 'parameters': [ - { - 'name': 'abcEfg_A', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - } - ], - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - - try { - - const results = await spectral.run(validDocument); - expect(results.length).to.equal(0, 'Error count should be 0'); - - } catch (error) { - - throw new Error(error); - - } - - }); - - - // If a server encounters a query parameter that does not follow the naming - // conventions above, and the server does not know how to process it as a - // query parameter from this specification, it MUST return 400 Bad Request - // https://jsonapi.org/format/1.0/#query-parameters - // Test case for invalid parameter names - it('should return an error for invalid parameter names', async function () { - - const documentWithInvalidParameterName = { - 'openapi': '3.0.2', - 'paths': { - '/myResources': { - 'get': { - 'parameters': [ - { - 'name': 'abcefg', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - } - ], - 'responses': { - '400': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - - try { - - const results = await spectral.run(documentWithInvalidParameterName); - - // Check for error length - expect(results.length).to.be.greaterThan(0, 'Error count should be greater than 0'); - - // Check for severity - expect(results[0].severity).to.equal(DiagnosticSeverity.Error); - - } catch (error) { - - throw new Error(error); - - } - - }); - - - // https://support.stoplight.io/s/article/Does-Stoplight-support-query-parameters - // Test case for query parameters with no errors - it('should pass with no errors for valid query parameters', async function () { - - const validQueryParametersDocument = { - 'openapi': '3.0.2', - 'paths': { - '/myResources': { - 'get': { - 'parameters': [ - { - 'name': 'abcEfg_A', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - }, - { - 'name': 'a_b', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - } - ], - 'responses': { - '200': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - - try { - - const results = await spectral.run(validQueryParametersDocument); - expect(results.length).to.equal(0, 'Error count should be 0'); - - } catch (error) { - - throw new Error(error); - - } - - }); - - // https://support.stoplight.io/s/article/Does-Stoplight-support-query-parameters - // test case for bad parameter name with one non a-z character - it('should return an error for bad parameter name with one non a-z character', async function () { - - const badParameterNameDocument = { - 'openapi': '3.0.2', - 'paths': { - // second parameter is the bad one - '/myResources': { - 'get': { - 'parameters': [ - { - 'name': 'abcEfg_A', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - }, - // this parameter is a baddie - { - 'name': 'ab@', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - } - ], - 'responses': { - '400': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - - try { - - const results = await spectral.run(badParameterNameDocument); - - // Check that an error is returned - expect(results.length).to.be.greaterThan(0, 'At least one error should be returned'); - - // Check for the correct error code - expect(results[0].code).to.equal('get-filter-query-parameters', 'Incorrect error code'); - - // Optionally, check for severity level - expect(results[0].severity).to.equal(DiagnosticSeverity.Error, 'Severity should be "Error"'); - - } catch (error) { - - throw new Error(error); - - } - - }); - - // https://support.stoplight.io/s/article/Does-Stoplight-support-query-parameters - // Test case for bad parameter name with a number - it('should return an error for bad parameter name with a number', async function () { - - const badParameterNumberDocument = { - 'openapi': '3.0.2', - 'paths': { - '/myResources': { - 'get': { - 'parameters': [ - { - 'name': '33', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - } - ], - 'responses': { - '400': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - - try { - - const results = await spectral.run(badParameterNumberDocument); - - // Check that an error is returned - expect(results.length).to.be.greaterThan(0, 'At least one error should be returned'); - - // Check for the correct error code - expect(results[0].code).to.equal('get-filter-query-parameters', 'Incorrect error code'); - - // Optionally, check for severity level - expect(results[0].severity).to.equal(DiagnosticSeverity.Error, 'Severity should be "Error"'); - - } catch (error) { - - throw new Error(error); - - } - - }); - - // Test case for bad parameter name with unallowed special characters - it('should return an error for bad parameter name with unallowed special characters', async function () { - - const badParameterSpecialCharDocument = { - 'openapi': '3.0.2', - 'paths': { - '/myResources': { - 'get': { - 'parameters': [ - { - 'name': 'A_-___', - 'description': 'schema for \'fields\' query parameter', - 'in': 'query', - 'schema': { - 'type': 'string' - } - } - ], - 'responses': { - '400': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {}, - 'data:': { - 'type': 'object', - 'properties': { - 'meta': {} - } - } - } - } - } - } - } - } - }, - 'patch': { - 'requestBody': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'jsonapi': {}, - 'meta': {} - } - } - } - } - } - } - } - } - }; - - try { - - const results = await spectral.run(badParameterSpecialCharDocument); - - // Check that an error is returned - expect(results.length).to.be.greaterThan(0, 'At least one error should be returned'); - - // Check for the correct error code - expect(results[0].code).to.equal('member-names-end_with', 'Incorrect error code'); - - // Optionally, check for severity level - expect(results[0].severity).to.equal(DiagnosticSeverity.Error, 'Severity should be "Error"'); - - } catch (error) { - - throw new Error(error); - - } - - }); - - -}); diff --git a/test/testsSetup.js b/test/testsSetup.js deleted file mode 100644 index d3917b6..0000000 --- a/test/testsSetup.js +++ /dev/null @@ -1,12 +0,0 @@ -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import { resolveRef } from './utils/refResolver.js'; -import validApiDocument from './docs/validApiDocument.js'; - -chai.use(chaiAsPromised); - -// Export chai's expect to be globally available -global.expect = chai.expect; - -// Dereference the validApiDocument and make it globally available -global.dereferencedValidOpenApiDocument = resolveRef(validApiDocument, validApiDocument); diff --git a/test/utils/.eslintrc.yml b/test/utils/.eslintrc.yml deleted file mode 100644 index bd64776..0000000 --- a/test/utils/.eslintrc.yml +++ /dev/null @@ -1,7 +0,0 @@ -rules: - max-params: - - error - - max: 4 - complexity: - - error - - max: 8 \ No newline at end of file diff --git a/test/utils/debugUtils.js b/test/utils/debugUtils.js deleted file mode 100644 index 3590444..0000000 --- a/test/utils/debugUtils.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * A utility module for handling debug logs with different levels (log, debug, warn, error, info). - * Each level can be independently enabled via specific environment variables: - * - LOG_DEBUG: Enables general logging. - * - DEBUG_DEBUG: Enables detailed debugging messages. - * - WARN_DEBUG: Enables warning messages. - * - ERROR_DEBUG: Enables error messages. - * - INFO_DEBUG: Enables informational messages. - */ - -/** - * Checks if a specific debug mode is enabled based on an environment variable. - * @param {string} envVar - The environment variable to check. - * @returns {boolean} True if the debug mode is enabled, false otherwise. - */ -const isDebugModeEnabled = (envVar) => { - - return process.env[envVar] === 'true'; - -}; - -/** - * Logs a general message to the console if LOG_DEBUG is enabled. - * @param {String} message - The message to log. - * @return {void} - */ -export const debugLog = (message) => { - - if (isDebugModeEnabled('LOG_DEBUG')) { - - console.log(`\x1b[33m[\x1b[0m \x1b[1mLOG \x1b[0m\x1b[33m ] \x1b[0m${message}`); - - } - -}; - -/** - * Outputs a debugging message to the console if DEBUG_DEBUG is enabled. - * @param {string} message - The debugging message to output. - * @return {void} - */ -export const debugDebug = (message) => { - - if (isDebugModeEnabled('DEBUG_DEBUG')) { - - console.debug(`\x1b[36m[\x1b[0m \x1b[1mDEBUG \x1b[0m\x1b[36m ] \x1b[35m${message}\x1b[0m`); - - } - -}; - -/** - * Outputs a warning message to the console if WARN_DEBUG is enabled. - * @param {string} message - The warning message to output. - * @return {void} - */ -export const debugWarn = (message) => { - - if (isDebugModeEnabled('WARN_DEBUG')) { - - console.warn(message); - - } - -}; - -/** - * Outputs an error message to the console if ERROR_DEBUG is enabled. - * @param {string} message - The error message to output. - * @return {void} - */ -export const debugError = (message) => { - - if (isDebugModeEnabled('ERROR_DEBUG')) { - - console.error(`\x1b[31m[\x1b[0m \x1b[1mERROR \x1b[0m\x1b[31m ] \x1b[33m${message}\x1b[0m`); - - } - -}; - -/** - * Outputs an informational message to the console if INFO_DEBUG is enabled. - * @param {string} message - The information message to output. - * @return {void} - */ -export const debugInfo = (message) => { - - if (isDebugModeEnabled('INFO_DEBUG')) { - - console.info(`\x1b[32m[\x1b[0m \x1b[1mINFO \x1b[0m\x1b[32m ] \x1b[36m${message}\x1b[0m`); - - } - -}; diff --git a/test/utils/disableAllRulesets.js b/test/utils/disableAllRulesets.js deleted file mode 100644 index fcfbcc9..0000000 --- a/test/utils/disableAllRulesets.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable no-prototype-builtins */ -/** - * Disables all rules within a given Spectral instance. - * This function iterates through the rules in the Spectral ruleset and sets each rule's enabled status to false. - * It is typically used in testing scenarios to ensure that no rules are active before selectively enabling specific rules for a test. - * - * @param {Spectral} spectral - An instance of Spectral, which is the core object used for linting in Spectral. - * - * Example Usage: - * - To disable all rules in a Spectral instance before running tests, call disableAllRulesets(spectral). - * - * Notes: - * - The function modifies the Spectral instance in place and does not return a value. - * - This is a utility function intended for test setup, where you might need to start with all rules disabled - * before enabling only those relevant to the test being executed. - * - Ensure that the Spectral instance passed to this function has been properly initialized with a ruleset. - * @returns {void} - */ -export function disableAllRulesets(spectral) { - - for (const rule in spectral.ruleset.rules) { - - if (spectral.ruleset.rules.hasOwnProperty(rule)) { - - spectral.ruleset.rules[rule].enabled = false; - - } - - } - -} diff --git a/test/utils/displayRulesets.js b/test/utils/displayRulesets.js deleted file mode 100644 index de678ae..0000000 --- a/test/utils/displayRulesets.js +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable no-prototype-builtins */ -import { debugInfo } from './debugUtils.js'; - -/** - * Logs the current enabled/disabled state of each rule in the Spectral instance's ruleset. - * This function iterates through all rules in the Spectral ruleset and logs their names along with their enabled/disabled status. - * It is particularly useful for debugging and testing purposes to ensure that the correct rules are enabled or disabled before running validations. - * - * @param {Spectral} spectral - An instance of Spectral, which contains the ruleset whose rules' states are to be displayed. - * - * Example Usage: - * - Call displayRulesets(spectral) to print the enabled/disabled status of all rules in the given Spectral instance. - * - * Notes: - * - The function does not return any value; its primary purpose is to log information to the console. - * - It uses ANSI color codes to visually distinguish between enabled (green) and disabled (red) rules. - * - Ensure that console logging is appropriate for your use case (e.g., debugging) as it may not be suitable in production environments. - * @returns {void} - */ -export function displayRulesets(spectral) { - - debugInfo(` \x1b[4mAll Rulesets\x1b[0m: `); - - for (const rule in spectral.ruleset.rules) { - - if (spectral.ruleset.rules.hasOwnProperty(rule)) { - - debugInfo(`\x1b[35m -\x1b[33m ${rule}: ${spectral.ruleset.rules[rule].enabled - ? '\x1b[32mEnabled\x1b[0m' - : '\x1b[31mDisabled\x1b[0m'}`); - - } - - } - - debugInfo(`\n`); - -} diff --git a/test/utils/enableSpecificRuleset.js b/test/utils/enableSpecificRuleset.js deleted file mode 100644 index df459a1..0000000 --- a/test/utils/enableSpecificRuleset.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-prototype-builtins */ - -import { debugDebug } from './debugUtils.js'; - -/** - * Enables a specific set of rules within a Spectral instance. - * This function iterates through an array of ruleset names and enables each specified rule within the Spectral instance. - * It's particularly useful in testing scenarios where only a subset of rules should be active for a particular test case. - * - * @param {Spectral} spectral - An instance of Spectral, which is the core object used for linting in Spectral. - * @param {string[]} rulesetNames - An array of strings representing the names of the rules to be enabled. - * @return {void} - * - * Example Usage: - * - To enable the rules 'rule1' and 'rule2' in a Spectral instance, call enableSpecificRuleset(spectral, ['rule1', 'rule2']). - * - * Notes: - * - The function assumes that the Spectral instance and the ruleset are properly initialized. - * - Only rules that exist in the Spectral instance's ruleset are enabled; if a rule name does not exist, it is ignored. - * - This function is crucial for targeted testing, allowing for the selective enabling of rules based on the test being executed. - */ -export function enableSpecificRuleset(spectral, rulesetNames) { - - debugDebug(`\x1b[35mExtracted Rules From Title:\x1b[0m\x1b[36m ${rulesetNames}\n`); - debugDebug(`\x1b[35mTotal Rules From Title:\x1b[0m\x1b[36m ${rulesetNames.length}\n\n\x1b[0m`); - - for (const rulesetName of rulesetNames) { - - if (spectral.ruleset.rules.hasOwnProperty(rulesetName)) { - - spectral.ruleset.rules[rulesetName].enabled = true; - - } - - } - -} diff --git a/test/utils/formattedErrorMessage.js b/test/utils/formattedErrorMessage.js deleted file mode 100644 index 8260741..0000000 --- a/test/utils/formattedErrorMessage.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Formats an error message for readability. It replaces escaped - * characters with their unescaped counterparts. - * - * @param {error} error - The error object that needs formatting. - * @returns {string} A formatted, human-readable error message. - */ -export function formattedErrorMessage(error) { - - // Handle cases where error or error.message is undefined - if (!error || !error.message) { - - return ''; - - } - - // Convert error object to string if necessary - const errorString = typeof error.message === 'string' - ? error.message - : JSON.stringify(error.message, null, 2); - - // Replace escaped characters like '\"' with '"' - const readableErrorMessage = errorString.replace(/\\\\"/gu, '"').replace(/\\n/gu, '\n'); - - return readableErrorMessage; - -} diff --git a/test/utils/getAllRulesets.js b/test/utils/getAllRulesets.js deleted file mode 100644 index 3f37436..0000000 --- a/test/utils/getAllRulesets.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable no-console */ - -import { debugError } from './debugUtils.js'; - -/** - * Extracts all rule names from a given Spectral ruleset. - * This function is designed to retrieve the keys (rule names) from the rules object within a Spectral ruleset. - * It's useful for scenarios where you need to know all the rules defined in a ruleset, - * such as in test setup or dynamic rule manipulation. - * - * @param {Object} ruleset - A Spectral ruleset object. The ruleset should have a 'rules' property containing the defined rules. - * @returns {string[]} An array of rule names present in the ruleset. If the ruleset is empty, invalid, or has no rules, it returns an empty array. - * - * Example Usage: - * - Given a ruleset with rules named 'rule1', 'rule2', 'rule3', getAllRulesets(ruleset) would return ['rule1', 'rule2', 'rule3']. - * - * Notes: - * - The function performs a check to ensure the ruleset is properly structured with a 'rules' property. - * - If the provided ruleset is invalid or has no rules, the function logs a warning to the console and returns an empty array. - * - This function is primarily used for setup and configuration purposes in testing and rule management scenarios. - */ -export function getAllRulesets(ruleset) { - - if (!ruleset || !ruleset.rules || Object.keys(ruleset.rules).length === 0) { - - debugError('No rules found in the provided ruleset.'); - - return []; - - } - - return Object.keys(ruleset.rules); - -} diff --git a/test/utils/getEnabledRules.js b/test/utils/getEnabledRules.js deleted file mode 100644 index 55c7e48..0000000 --- a/test/utils/getEnabledRules.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Retrieves a list of currently enabled rules from a given Spectral instance. - * This function iterates over all the rules in the Spectral ruleset and constructs an object - * where the keys are the names of the enabled rules and their corresponding values are set to true. - * - * @param {Spectral} spectral - An instance of Spectral, which is the core object used for linting in Spectral. - * @returns {Object} An object containing the enabled rule names as keys, all set to true. - * If no rules are enabled or if the Spectral instance is not properly configured, it returns an empty object. - * - * Example Usage: - * - Given a Spectral instance with 'rule1' and 'rule2' enabled, getEnabledRules(spectral) would return: { rule1: true, rule2: true } - * - * Notes: - * - The function assumes that the Spectral instance passed to it has been properly initialized and configured with a ruleset. - * - This function is useful for scenarios where you need to identify which rules are active in Spectral's current state, - * particularly in dynamic testing environments where rules might be enabled or disabled programmatically. - */ -export function getEnabledRules(spectral) { - - const enabledRules = {}; - for (const [ruleName, ruleDetails] of Object.entries(spectral.ruleset.rules)) { - - if (ruleDetails.enabled) { - - enabledRules[ruleName] = true; - - } - - } - - return enabledRules; - -} diff --git a/test/utils/getRulesFromTestTitle.js b/test/utils/getRulesFromTestTitle.js deleted file mode 100644 index 2b32571..0000000 --- a/test/utils/getRulesFromTestTitle.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable no-plusplus */ -/* eslint-disable complexity */ -/* eslint-disable no-cond-assign */ - -import { debugError, debugDebug } from './debugUtils.js'; - -/** - * Extracts and returns rules from a test title string. - * - * @param {string} ruleName - The test title string from which to extract rule names. - * @param {Array.} rules - An array of all possible rule names to match against. - * @returns {Array. | null} An array containing the current rule name, or an empty array if not found. - */ -export function getRulesFromTestTitle(ruleName, rules) { - - if (!ruleName) { - - debugError('No rule name provided.'); - - return []; - - } - - if (rules.length === 0) { - - debugError('No rules available to match.'); - - return []; - - } - - debugDebug(`\x1b[35mCurrent Test Title:\x1b[0m\x1b[36m ${ruleName} \n\x1b[0m`); - - // debugDebug(`\ngetRulesFromTestTitle title param: ${title}`); - // debugDebug(`\ngetRulesFromTestTitle rules param: ${rules}`); - - // const rulePattern = /\|(?[\w-]+)\|/gu; - // const matchingRules = []; - // let match; - // let count = 0; - - // while ((match = rulePattern.exec(title)) !== null && count < 5) { - // while ((match = rulePattern.exec(title)) !== null) { - - // const { ruleName } = match.groups; - - // // debugDebug(`while 'ruleName': ${ruleName}`); - - // if (rules.includes(ruleName)) { - - // matchingRules.push(ruleName); - - // } - - // // break; - // // count++; - - // } - - // debugDebug(`Matched Rule: ${matchingRules}`); - - // return matchingRules; - - if (rules.includes(ruleName)) { - - return [ruleName]; - - } - - return []; - -} diff --git a/test/utils/handleSpectralResults.js b/test/utils/handleSpectralResults.js deleted file mode 100644 index 9127392..0000000 --- a/test/utils/handleSpectralResults.js +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable arrow-body-style */ -import { debugError, debugDebug } from './debugUtils.js'; -import { getEnabledRules } from './getEnabledRules.js'; - -/** - * @function handleSpectralResults - * @description Filters and handles the results of the spectral run. - * @param {Object} spectral - The Spectral instance. - * @param {Object} document - The document to be tested. - * @param {string} resultCode - The result code to filter the results by. - * @returns {Promise} The relevant results. - */ -export async function handleSpectralResults(spectral, document, resultCode) { - - try { - - const enabledRules = getEnabledRules(spectral); - - // Log the details of the rule, if it exists - // if (spectral.ruleset.rules[resultCode]) { - - // debugDebug(`\x1b[35mRule Details:\x1b[36m ${JSON.stringify(spectral.ruleset.rules[resultCode], null, 2)}\n`); - // debugDebug(`\x1b[35mRule Message:\x1b[36m ${spectral.ruleset.rules[resultCode].message}\n`); - // debugDebug(`\x1b[35mRule Given:\x1b[36m ${spectral.ruleset.rules[resultCode].given}\n`); - // debugDebug(`\x1b[35mRule Then:\x1b[36m ${JSON.stringify(spectral.ruleset.rules[resultCode].then, null, 2)}\n\n\x1b[0m\n`); - - // } - - const results = await spectral.run(document, { rules: enabledRules }); - - // debugDebug(`Document Results: ${JSON.stringify(document, null, 2)} \x1b[0m\n`); - - // debugDebug(`Before forEach loop, numer of results, ${results.length}\n`); - - // Log each result, including targetVal - results.forEach((result) => { - - debugDebug(`Handle Spectral Results Utils - Spectral's Run Output\n`); - - // Spectral provides an output of the results for reasons why it has potentially failed, below are the details to possibly fix them. - debugDebug(`Result code: \x1b[32m${result.code}\x1b[0m`); - // Since we are mapping the results path, we need to confirm that is an a provided path to avoid a `TypeError: undefined` message. - if (result.path) { - - debugDebug(`Result path: \x1b[33m[ \x1b[32m${result.path.map((item) => `\x1b[33m"\x1b[32m${item}\x1b[33m"`).join(', ')} \x1b[33m]\x1b[0m`); - - } - debugDebug(`Result message: \x1b[32m${result.message}\x1b[0m`); - // debugDebug(`Result severity: \x1b[32m${result.severity}\x1b[0m`); - // debugDebug(`Result range: \x1b[32m${JSON.stringify(result.range, null, 2)}\x1b[0m`); - // debugDebug(`Result source: \x1b[32m${result.source}\x1b[0m\n`); - - - // If the rule name is found in both `result.code` & resultCode`, this statement will process - // If the rule name does NOT match, this statement will not run and will need to review the - // `Result Code` output for potential issues with Spectral Run has failed. - if (result.code === resultCode) { - - debugDebug(`\x1b[32mResult for '${resultCode}':\x1b[36m ${JSON.stringify(result, ['message', 'path'], 2)} \x1b[0m\n`); - - } - - }); - - return results.filter((result) => result.code === resultCode); - - } catch (error) { - - debugError('An error occurred while running Spectral: ', error); - throw error; - - } - -} diff --git a/test/utils/processErrors.js b/test/utils/processErrors.js deleted file mode 100644 index 72435fc..0000000 --- a/test/utils/processErrors.js +++ /dev/null @@ -1,59 +0,0 @@ -/* eslint-disable no-undef */ - -import { debugError } from './debugUtils.js'; - -/** - * Processes and logs errors, specifically handling AggregateErrors separately. - * This function checks if the provided error is an instance of AggregateError. If so, - * it iterates over each individual error within the aggregate and logs them separately. - * For all other types of errors, it logs them as unexpected errors. This utility is - * particularly useful for handling and debugging multiple errors that can occur during - * Spectral setup or execution. - * - * @param {Error | AggregateError} error - The error object to process. Can be an instance of Error or AggregateError. - * - * Example Usage: - * - To process a caught error in a try-catch block, call processErrors(error). - * - * Notes: - * - This function re-throws the received error after logging, allowing for further handling or propagation. - * - The function is designed to enhance error visibility, especially useful in complex asynchronous operations - * where multiple errors might occur and be wrapped in an AggregateError. - * - Consider customizing the error logging or handling based on the application's needs. - * @returns {void} - */ -export function processErrors(error) { - - if (error instanceof AggregateError) { - - debugError(`AggregateError encountered with multiple errors:\x1b[0m\n`); - - for (const individualError of error.errors) { - - debugError(`Individual error:\x1b[35m ${individualError}\n\x1b[0m`); - - // Log more details if available - if (individualError instanceof Error) { - - debugError(`Error Message:\x1b[35m ${individualError.message}\x1b[0m`); - debugError(`Error stack:\x1b[35m ${individualError.stack}\x1b[0m`); - - } - - } - - } else { - - debugError(`Unexpected error during Spectral setup:\x1b[35m ${error}\n`); - - // if (error instanceof Error) { - // debugError(`Error Message:\x1b[35m ${error.message}`); - // debugError(`Error stack:\x1b[35m ${error.stack}`); - // } - - } - - // Re-throw the error for further handling or logging if needed. - throw error; - -} diff --git a/test/utils/refResolver.js b/test/utils/refResolver.js deleted file mode 100644 index 7508cd1..0000000 --- a/test/utils/refResolver.js +++ /dev/null @@ -1,134 +0,0 @@ -/* eslint-disable no-use-before-define */ -/** - * Retrieves and resolves the object pointed to by a `$ref` string in the root document. - * It checks if the reference has already been resolved to avoid duplication and circular references. - * If not, it navigates through the JSON structure based on the `$ref` path and returns the resolved object. - * - * @param {string} ref - The `$ref` string specifying the path to the object. - * @param {Object} root - The root document which contains the reference definitions. - * @param {Set} resolvedRefs - A set of resolved reference paths to detect circular references. - * @param {Object} resolvedObjects - A map of previously resolved objects to reuse and prevent recursion. - * @returns {Object} - The resolved object referred to by the `$ref` path. - * @throws {Error} - If the reference path is invalid or the reference cannot be found in the root document. - */ -function getRefObject(ref, root, resolvedRefs, resolvedObjects) { - - // Check and return early if already resolved - if (resolvedRefs.has(ref)) { - - return resolvedObjects[ref]; - - } - - resolvedRefs.add(ref); - - // Resolve the path to the object - const path = ref.replace(/^#\//u, '').split('/'); - let current = root; - for (const segment of path) { - - if (!current || typeof current !== 'object') { - - throw new Error(`Invalid reference path: ${ref}`); - - } - - current = current[segment]; - - } - - if (typeof current === 'undefined') { - - throw new Error(`Reference not found: ${ref}`); - - } - - const resolvedObject = resolveRef(current, root, resolvedRefs, resolvedObjects); - resolvedObjects[ref] = resolvedObject; - - return resolvedObject; - -} - -/** -* Resolves references within an object. This function iterates over each property of the object. -* If the property is an object or array, it resolves any `$ref` references within it recursively. -* It uses the provided sets to track and reuse resolved references and to detect circular references. -* -* @param {Object} obj - The object to resolve references in. -* @param {Object} root - The root document which contains the reference definitions. -* @param {Set} resolvedRefs - A set of resolved reference paths to detect circular references. -* @param {Object} resolvedObjects - A map of previously resolved objects to reuse and prevent recursion. -* @returns {Object} - The object with resolved references. -*/ -function resolveObject(obj, root, resolvedRefs, resolvedObjects) { - - const resolvedObj = {}; - for (const key in obj) { - - if (Object.prototype.hasOwnProperty.call(obj, key)) { - - resolvedObj[key] = resolveRef(obj[key], root, resolvedRefs, resolvedObjects); - - } - - } - - return resolvedObj; - -} - -/** -* Recursively resolves `$ref` references in an OpenAPI document. This function handles objects and arrays, -* resolving all `$ref` references found within. It supports nested structures and arrays, handles circular -* references, and removes resolved references from the `components` section if they are no longer needed. -* -* @param {Object|Array} obj - The object or array to resolve references in. -* @param {Object} root - The root document which contains the reference definitions. -* @param {Set} resolvedRefs - A set of resolved reference paths to detect circular references (default is an empty set). -* @param {Object} resolvedObjects - A map of previously resolved objects to reuse and prevent recursion (default is an empty object). -* @returns {Object|Array} - The object or array with resolved references. -*/ -export function resolveRef(obj, root, resolvedRefs = new Set(), resolvedObjects = {}) { - - if (Array.isArray(obj)) { - - return obj.map((item) => { - - return resolveRef(item, root, resolvedRefs, resolvedObjects); - - }); - - } else if (obj && typeof obj === 'object') { - - if ('$ref' in obj) { - - // const resolved = getRefObject(obj.$ref, root, resolvedRefs, resolvedObjects); - // // Remove the reference from 'components' if it's there - // if (obj.$ref.startsWith('#/components/')) { - - // const path = obj.$ref.replace(/^#\/components\//u, '').split('/'); - // let current = root.components; - // const lastSegment = path.pop(); - // for (const segment of path) { - - // current = current[segment]; - - // } - // delete current[lastSegment]; - - // } - - // return resolved; - - return getRefObject(obj.$ref, root, resolvedRefs, resolvedObjects); - - } - - return resolveObject(obj, root, resolvedRefs, resolvedObjects); - - } - - return obj; - -} diff --git a/test/utils/setupSpectral.js b/test/utils/setupSpectral.js deleted file mode 100644 index 1040596..0000000 --- a/test/utils/setupSpectral.js +++ /dev/null @@ -1,28 +0,0 @@ -import spectralCore from '@stoplight/spectral-core'; -import { disableAllRulesets } from './disableAllRulesets.js'; -import { debugInfo } from './debugUtils.js'; - -const { Spectral } = spectralCore; - -/** - * Sets up a new Spectral instance and sets its ruleset - * - * @param {Object} ruleset - The ruleset to be applied to the Spectral instance. - * @returns {Object} The Initialized Spectral isntance. - */ -export default function setupSpectral(ruleset) { - - debugInfo(`\n\n\x1b[34m==================================\x1b[0m Setting Up Test Case \x1b[34m==================================\x1b[0m`); - - const spectral = new Spectral(); - - spectral.setRuleset(ruleset); - - disableAllRulesets(spectral); - - // Enable this to log details for the entire ruleset results - // debugDebug(`\x1b[35m Spectral Results:\x1b[36m ${JSON.stringify(spectral.ruleset, null, 2)}\x1b[0m\n`); - - return spectral; - -} diff --git a/test/utils/setupSpectralBeforeEach.js b/test/utils/setupSpectralBeforeEach.js deleted file mode 100644 index 8c728f9..0000000 --- a/test/utils/setupSpectralBeforeEach.js +++ /dev/null @@ -1,51 +0,0 @@ -import { displayRulesets } from './displayRulesets.js'; -import { enableSpecificRuleset } from './enableSpecificRuleset.js'; -import { processErrors } from './processErrors.js'; -import setupSpectral from './setupSpectral.js'; - -/** - * Creates a beforeEach function for Mocha tests, setting up Spectral with a given ruleset and enabling specific rules. - * - * @param {Object} ruleset - The Spectral ruleset to be used in the tests. - * @param {string} ruleName - A rule name to be enabled for the test suite. If empty, all rules are used. - * @param {Function} [setupSpectralFn=setupSpectral] - Optional function to setup Spectral. Defaults to the standard setupSpectral function. - * @returns {Function} A function to be used in the beforeEach hook in Mocha tests. - * - * @example - * // In your test file - * beforeEach(setupSpectralBeforeEach(myRuleset, 'rule-set-name')); - * - * @example - * // Using with a custom setupSpectral function - * beforeEach(setupSpectralBeforeEach(myRuleset, 'rule-set-name', customSetupSpectral)); - */ -export function setupSpectralBeforeEach(ruleset, ruleName, setupSpectralFn = setupSpectral) { - - return function () { - - let spectral; - - try { - - spectral = setupSpectralFn(ruleset); - - if (ruleName.length > 0) { - - enableSpecificRuleset(spectral, ruleName); - - } - - displayRulesets(spectral); - - } catch (error) { - - processErrors(error); - - } - - // Make spetral available in the test context - this.spectral = spectral; - - }; - -} diff --git a/test/utilsTests/.eslintrc.yml b/test/utilsTests/.eslintrc.yml deleted file mode 100644 index 0fc7980..0000000 --- a/test/utilsTests/.eslintrc.yml +++ /dev/null @@ -1,2 +0,0 @@ -rules: - no-useless-escape: off \ No newline at end of file diff --git a/test/utilsTests/debugUtils.test.js b/test/utilsTests/debugUtils.test.js deleted file mode 100644 index f8f6511..0000000 --- a/test/utilsTests/debugUtils.test.js +++ /dev/null @@ -1,132 +0,0 @@ -import sinon from 'sinon'; -import * as debugUtils from '../utils/debugUtils.js'; - -describe('debug Utils Test Suite:', function () { - - let consoleStub; - - beforeEach(function () { - - // Setup stubs for console methods before each test - consoleStub = { - log: sinon.stub(console, 'log'), - debug: sinon.stub(console, 'debug'), - info: sinon.stub(console, 'info'), - warn: sinon.stub(console, 'warn'), - error: sinon.stub(console, 'error') - }; - - }); - - afterEach(function () { - - // Restore the original console methods after each test - consoleStub.log.restore(); - consoleStub.debug.restore(); - consoleStub.info.restore(); - consoleStub.warn.restore(); - consoleStub.error.restore(); - - }); - - describe('debugLog:', function () { - - it('should call console.log when LOG_DEBUG is enabled', function () { - - process.env.LOG_DEBUG = 'true'; - debugUtils.debugLog('Log Message'); - expect(consoleStub.log.calledWith('\x1b[33m[\x1b[0m \x1b[1mLOG \x1b[0m\x1b[33m ] \x1b[0mLog Message')).to.be.true; - - }); - - it('should call console.log when LOG_DEBUG is disabled', function () { - - process.env.LOG_DEBUG = 'false'; - debugUtils.debugLog('Log Message'); - expect(consoleStub.log.called).to.be.false; - - }); - - }); - - describe('debugDebug:', function () { - - it('should call console.debug when DEBUG_DEBUG is enabled', function () { - - process.env.DEBUG_DEBUG = 'true'; - debugUtils.debugDebug('Debug Message'); - expect(consoleStub.debug.calledWith('\x1b[36m[\x1b[0m \x1b[1mDEBUG \x1b[0m\x1b[36m ] \x1b[35mDebug Message\x1b[0m')).to.be.true; - - }); - - it('should call console.debug when DEBUG_DEBUG is disabled', function () { - - process.env.DEBUG_DEBUG = 'false'; - debugUtils.debugDebug('Debug Message'); - expect(consoleStub.debug.called).to.be.false; - - }); - - }); - - describe('debugInfo:', function () { - - it('should call console.info when INFO_DEBUG is enabled', function () { - - process.env.INFO_DEBUG = 'true'; - debugUtils.debugInfo('Info Message'); - expect(consoleStub.info.calledWith('\x1b[32m[\x1b[0m \x1b[1mINFO \x1b[0m\x1b[32m ] \x1b[36mInfo Message\x1b[0m')).to.be.true; - - }); - - it('should call console.info when INFO_DEBUG is disabled', function () { - - process.env.INFO_DEBUG = 'false'; - debugUtils.debugInfo('Info Message'); - expect(consoleStub.info.called).to.be.false; - - }); - - }); - - describe('debugWarn:', function () { - - it('should call console.warn when WARN_DEBUG is enabled', function () { - - process.env.WARN_DEBUG = 'true'; - debugUtils.debugWarn('Warn Message'); - expect(consoleStub.warn.calledWith('Warn Message')).to.be.true; - - }); - - it('should call console.warn when WARN_DEBUG is disabled', function () { - - process.env.WARN_DEBUG = 'false'; - debugUtils.debugWarn('Warn Message'); - expect(consoleStub.warn.called).to.be.false; - - }); - - }); - - describe('debugError:', function () { - - it('should call console.error when ERROR_DEBUG is enabled', function () { - - process.env.ERROR_DEBUG = 'true'; - debugUtils.debugError('Error Message'); - expect(consoleStub.error.calledWith('\x1b[31m[\x1b[0m \x1b[1mERROR \x1b[0m\x1b[31m ] \x1b[33mError Message\x1b[0m')).to.be.true; - - }); - - it('should call console.error when ERROR_DEBUG is disabled', function () { - - process.env.ERROR_DEBUG = 'false'; - debugUtils.debugError('Error Message'); - expect(consoleStub.error.called).to.be.false; - - }); - - }); - -}); diff --git a/test/utilsTests/disableAllRulesets.test.js b/test/utilsTests/disableAllRulesets.test.js deleted file mode 100644 index 4fb1e68..0000000 --- a/test/utilsTests/disableAllRulesets.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import pkg from '@stoplight/spectral-core'; -const { Spectral } = pkg; - -import { truthy } from '@stoplight/spectral-functions'; -import { disableAllRulesets } from '../utils/disableAllRulesets.js'; - -describe('disableAllRulesets Utils:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - spectral.setRuleset({ - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - }, - 'rule-two': { - description: 'Second Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - }); - - }); - - it('should disable all rules', function () { - - disableAllRulesets(spectral); - expect(spectral.ruleset.rules['rule-one'].enabled).to.be.false; - expect(spectral.ruleset.rules['rule-two'].enabled).to.be.false; - - }); - -}); diff --git a/test/utilsTests/displayRulesets.test.js b/test/utilsTests/displayRulesets.test.js deleted file mode 100644 index 8c0b0dc..0000000 --- a/test/utilsTests/displayRulesets.test.js +++ /dev/null @@ -1,90 +0,0 @@ -import pkg from '@stoplight/spectral-core'; -const { Spectral } = pkg; - -import { truthy } from '@stoplight/spectral-functions'; -import sinon from 'sinon'; -import { displayRulesets } from '../utils/displayRulesets.js'; -// import { debugDebug, debugError, debugInfo, debugLog, debugWarn } from '../utils/debugUtils.js'; - -describe('displayRulesets Utils:', function () { - - let spectral; - let consoleStub; - - beforeEach(function () { - - // Create a new Spectral instance and set up some rules - spectral = new Spectral(); - spectral.setRuleset({ - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - }, - 'rule-two': { - description: 'Second Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - }); - - // Setup stubs for console methods before each test - consoleStub = { - info: sinon.stub(console, 'info') - }; - - }); - - afterEach(function () { - - // Restore the original console methods after each test - consoleStub.info.restore(); - - }); - - it('should correctly log the status of each rule in the ruleset', function () { - - process.env.INFO_DEBUG = true; - - spectral.ruleset.rules['rule-one'].enabled = true; - spectral.ruleset.rules['rule-two'].enabled = false; - - displayRulesets(spectral); - - const enabledRegex = /rule-one.*Enabled/u; - const disabledRegex = /rule-two.*Disabled/u; - - let foundEnabled = false; - let foundDisabled = false; - - consoleStub.info.getCalls().forEach((call) => { - - if (enabledRegex.test(call.args[0])) { - - foundEnabled = true; - - } - if (disabledRegex.test(call.args[0])) { - - foundDisabled = true; - - } - - }); - - expect(foundEnabled).to.be.true; - expect(foundDisabled).to.be.true; - - }); - -}); diff --git a/test/utilsTests/enableSpecificRuleset.test.js b/test/utilsTests/enableSpecificRuleset.test.js deleted file mode 100644 index a1a407f..0000000 --- a/test/utilsTests/enableSpecificRuleset.test.js +++ /dev/null @@ -1,50 +0,0 @@ -import pkg from '@stoplight/spectral-core'; -const { Spectral } = pkg; - -import { truthy } from '@stoplight/spectral-functions'; -import { enableSpecificRuleset } from '../utils/enableSpecificRuleset.js'; - -describe('enableSpecificRuleset Utils:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - spectral.setRuleset({ - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - }, - 'rule-two': { - description: 'Second Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - }); - - }); - - it('should enable specified rules', function () { - - spectral.ruleset.rules['rule-one'].enabled = false; - spectral.ruleset.rules['rule-two'].enabled = false; - - enableSpecificRuleset(spectral, ['rule-one']); - expect(spectral.ruleset.rules['rule-one'].enabled).to.be.true; - expect(spectral.ruleset.rules['rule-two'].enabled).to.be.false; - - }); - -}); diff --git a/test/utilsTests/formattedErrorMessage.test.js b/test/utilsTests/formattedErrorMessage.test.js deleted file mode 100644 index ade5c42..0000000 --- a/test/utilsTests/formattedErrorMessage.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import { formattedErrorMessage } from '../utils/formattedErrorMessage.js'; - -describe('formattedErrorMessage Utils Test Suite:', function () { - - describe('standardError:', function () { - - it('should format a simple error message', function () { - - const error = new Error('Test error message'); - const formattedMessage = formattedErrorMessage(error); - expect(formattedMessage).to.equal('Test error message'); - - }); - - }); - - describe('complexError:', function () { - - it('should format an error message with escaped characters', function () { - - const error = new Error(`Error with \"escaped\" characters\nNew line`); - const formattedMessage = formattedErrorMessage(error); - expect(formattedMessage).to.equal(`Error with \"escaped\" characters\nNew line`); - - }); - - }); - - describe('nonStandardError:', function () { - - it('should handle non-string error messages', function () { - - const error = { - message: { - detail: 'Error detail', - code: 500 - } - }; - const formattedMessage = formattedErrorMessage(error); - expect(formattedMessage).to.include('Error detail'); - expect(formattedMessage).to.include('500'); - - }); - - }); - - describe('blankError:', function () { - - it('should return an empty string for error with no message', function () { - - const error = { }; - const formattedMessage = formattedErrorMessage(error); - expect(formattedMessage).to.be.a('string').and.to.be.empty; - - }); - - }); - -}); diff --git a/test/utilsTests/getAllRulesets.test.js b/test/utilsTests/getAllRulesets.test.js deleted file mode 100644 index 4c70679..0000000 --- a/test/utilsTests/getAllRulesets.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { getAllRulesets } from '../utils/getAllRulesets.js'; - -describe('getAllRulesets Utils:', function () { - - it('should return all rule names from a given ruleset', function () { - - const ruleset = { - rules: { - 'rule-one': { }, - 'rule-two': { } - } - }; - expect(getAllRulesets(ruleset)).to.deep.equal(['rule-one', 'rule-two']); - - }); - - it('should return an empty array for an empty ruleset', function () { - - const ruleset = { rules: { } }; - expect(getAllRulesets(ruleset)).to.be.empty; - - }); - - it('should return an empty array for invalid ruleset', function () { - - const ruleset = null; - expect(getAllRulesets(ruleset)).to.be.empty; - - }); - -}); diff --git a/test/utilsTests/getEnabledRules.test.js b/test/utilsTests/getEnabledRules.test.js deleted file mode 100644 index 46e839d..0000000 --- a/test/utilsTests/getEnabledRules.test.js +++ /dev/null @@ -1,43 +0,0 @@ -import pkg from '@stoplight/spectral-core'; -const { Spectral } = pkg; - -import { truthy } from '@stoplight/spectral-functions'; -import { getEnabledRules } from '../utils/getEnabledRules.js'; - -describe('getEnabledRules Utils:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - spectral.setRuleset({ - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - }); - - }); - - it('should return the enabled rules', function () { - - expect(getEnabledRules(spectral)).to.deep.equal({ 'rule-one': true }); - - }); - - it('should return an empty object if no rules are enabled', function () { - - spectral.ruleset.rules['rule-one'].enabled = false; - expect(getEnabledRules(spectral)).to.be.empty; - - }); - -}); diff --git a/test/utilsTests/getRulesFromTestTitle.test.js b/test/utilsTests/getRulesFromTestTitle.test.js deleted file mode 100644 index c7e2d2b..0000000 --- a/test/utilsTests/getRulesFromTestTitle.test.js +++ /dev/null @@ -1,37 +0,0 @@ -import { getRulesFromTestTitle } from '../utils/getRulesFromTestTitle.js'; - -describe('getRulesFromTestTitle Utils:', function () { - - it('should return an array with a single rule name if it is in the rules list', function () { - - const ruleName = 'rule-name'; - const rules = ['rule-name', 'another-rule']; - expect(getRulesFromTestTitle(ruleName, rules)).to.deep.equal(['rule-name']); - - }); - - it('should return an empty array if the rule name is not in the rules list', function () { - - const ruleName = 'nonexistent-rule'; - const rules = ['rule-one', 'rule-two']; - expect(getRulesFromTestTitle(ruleName, rules)).to.be.empty; - - }); - - it('should return an empty array if no rule name is provided', function () { - - const ruleName = ''; - const rules = ['rule-one', 'rule-two']; - expect(getRulesFromTestTitle(ruleName, rules)).to.be.empty; - - }); - - it('should return an empty array if there are no rules provided', function () { - - const ruleName = 'rule-one'; - const rules = []; - expect(getRulesFromTestTitle(ruleName, rules)).to.be.empty; - - }); - -}); diff --git a/test/utilsTests/handleSpectralResults.test.js b/test/utilsTests/handleSpectralResults.test.js deleted file mode 100644 index cc33d7f..0000000 --- a/test/utilsTests/handleSpectralResults.test.js +++ /dev/null @@ -1,91 +0,0 @@ -import pkg from '@stoplight/spectral-core'; - -/* disable no-unused-vars */ -const { Spectral } = pkg; - -import { truthy } from '@stoplight/spectral-functions'; -import sinon from 'sinon'; -import { handleSpectralResults } from '../utils/handleSpectralResults.js'; - - -describe('handleSpectralResults Utils:', function () { - - let spectral; - - beforeEach(function () { - - spectral = new Spectral(); - spectral.setRuleset({ - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Message for rule-one', - severity: 'error', - given: '$', - then: { - function: truthy - } - }, - 'rule-two': { - description: 'Second Rule description', - message: 'Message for rule-two', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - }); - - sinon.stub(spectral, 'run').resolves([ - { - code: 'rule-one', - message: 'Message for rule-one' - }, - { - code: 'rule-two', - message: 'Message for rule-two' - } - ]); - - }); - - afterEach(function () { - - sinon.restore(); - - }); - - it('should filter results by a given resultCode', async function () { - - // Mock document - const document = { }; - const results = await handleSpectralResults(spectral, document, 'rule-one'); - expect(results).to.deep.equal([{ - code: 'rule-one', - message: 'Message for rule-one' - }]); - - }); - - it('should handle no matching results', async function () { - - // Mock document - const document = { }; - const results = await handleSpectralResults(spectral, document, 'nonexistent-rule'); - expect(results).to.be.empty; - - }); - - it('should throw error on Spectral run failure', function () { - - spectral.run.rejects(new Error('Spectral run failed')); - // Mock document - const document = { }; - - return expect(handleSpectralResults(spectral, document, 'rule-one')).to.eventually.be.rejectedWith('Spectral run failed'); - - }); - -}); diff --git a/test/utilsTests/processErrors.test.js b/test/utilsTests/processErrors.test.js deleted file mode 100644 index 820eafe..0000000 --- a/test/utilsTests/processErrors.test.js +++ /dev/null @@ -1,61 +0,0 @@ -import sinon from 'sinon'; -import { processErrors } from '../utils/processErrors.js'; - -describe('processErrors Utils:', function () { - - let consoleErrorStub; - - - beforeEach(function () { - - consoleErrorStub = sinon.stub(console, 'error'); - - }); - - afterEach(function () { - - consoleErrorStub.restore(); - - }); - - it('should handle AggregateError', function () { - - process.env.ERROR_DEBUG = true; - - const aggregateError = new AggregateError([ - new Error('Error One'), - new Error('Error Two') - ], 'Multiple errors occurred'); - - try { - - processErrors(aggregateError); - - } catch (error) { - - // One error for the AggregateError Message, two for the individual errors - expect(consoleErrorStub.callCount).to.be.above(3); - expect(error).to.equal(aggregateError); - - } - - }); - - it('should handle regular Error', function () { - - const error = new Error('Regular error'); - - try { - - processErrors(error); - - } catch (caughtError) { - - expect(consoleErrorStub.calledOnce).to.be.true; - expect(caughtError).to.equal(caughtError); - - } - - }); - -}); diff --git a/test/utilsTests/refResolver.test.js b/test/utilsTests/refResolver.test.js deleted file mode 100644 index 1195113..0000000 --- a/test/utilsTests/refResolver.test.js +++ /dev/null @@ -1,316 +0,0 @@ -import mockApiDocument from '../docs/utilsTests/mockApiDocument.js'; -import { resolveRef } from '../utils/refResolver.js'; - -describe('resolveRef Utils In OpenAPI:', function () { - - let dereferenceDocument; - - before(function () { - - // Derference the document before running the tests - dereferenceDocument = resolveRef(mockApiDocument, mockApiDocument); - - }); - - it('should resolve $ref references', function () { - - const expectedSchema = { - 'type': 'object', - 'properties': { - 'errors': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'links': { - 'type': 'object', - 'properties': { - 'about': { - 'type': 'string', - 'format': 'uri' - } - } - }, - 'status': { - 'type': 'string' - }, - 'code': { - 'type': 'string' - }, - 'title': { - 'type': 'string' - }, - 'detail': { - 'type': 'string' - }, - 'source': { - 'type': 'object', - 'properties': { - 'pointer': { - 'type': 'string' - }, - 'parameter': { - 'type': 'string' - }, - 'header': { - 'type': 'string' - } - } - }, - 'meta': { - 'type': 'object', - 'additionalProperties': true - } - }, - 'required': [ - 'detail' - ] - } - } - } - }; - - expect(dereferenceDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema).to.deep.equal(expectedSchema); - - }); - - it('should correctly resolve properties of ErrorObject', function () { - - const expectedSchema = { - 'paths': { - '/users/{userId}': { - 'get': { - 'responses': { - '400': { - 'content': { - 'application/vnd.api+json': { - 'schema': { - 'type': 'object', - 'properties': { - 'errors': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'links': { - 'type': 'object', - 'properties': { - 'about': { - 'type': 'string', - 'format': 'uri' - } - } - }, - 'status': { - 'type': 'string' - }, - 'code': { - 'type': 'string' - }, - 'title': { - 'type': 'string' - }, - 'detail': { - 'type': 'string' - }, - 'source': { - 'type': 'object', - 'properties': { - 'pointer': { - 'type': 'string' - }, - 'parameter': { - 'type': 'string' - }, - 'header': { - 'type': 'string' - } - } - }, - 'meta': { - 'type': 'object', - 'additionalProperties': true - } - }, - 'required': [ - 'detail' - ] - } - } - } - } - } - } - } - } - } - } - } - }; - - expect(dereferenceDocument.paths).to.deep.equal(expectedSchema.paths); - - }); - - it('should handle resolution of deeply nested $ref', function () { - - const expectedSchema = { - type: 'object', - properties: { - pointer: { type: 'string' }, - parameter: { type: 'string' }, - header: { type: 'string' } - } - }; - - expect(dereferenceDocument.paths['/users/{userId}'].get.responses['400'].content['application/vnd.api+json'].schema.properties.errors.items.properties.source).to.deep.equal(expectedSchema); - - }); - - it('should handle resolution when $ref is at the root of the document', function () { - - const expectedResolvedSchema = { - 'JsonApiError': { - 'type': 'object', - 'properties': { - 'errors': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'links': { - 'type': 'object', - 'properties': { - 'about': { - 'type': 'string', - 'format': 'uri' - } - } - }, - 'status': { - 'type': 'string' - }, - 'code': { - 'type': 'string' - }, - 'title': { - 'type': 'string' - }, - 'detail': { - 'type': 'string' - }, - 'source': { - 'type': 'object', - 'properties': { - 'pointer': { - 'type': 'string' - }, - 'parameter': { - 'type': 'string' - }, - 'header': { - 'type': 'string' - } - } - }, - 'meta': { - 'type': 'object', - 'additionalProperties': true - } - }, - 'required': [ - 'detail' - ] - } - } - } - }, - 'ErrorObject': { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - }, - 'links': { - 'type': 'object', - 'properties': { - 'about': { - 'type': 'string', - 'format': 'uri' - } - } - }, - 'status': { - 'type': 'string' - }, - 'code': { - 'type': 'string' - }, - 'title': { - 'type': 'string' - }, - 'detail': { - 'type': 'string' - }, - 'source': { - 'type': 'object', - 'properties': { - 'pointer': { - 'type': 'string' - }, - 'parameter': { - 'type': 'string' - }, - 'header': { - 'type': 'string' - } - } - }, - 'meta': { - 'type': 'object', - 'additionalProperties': true - } - }, - 'required': [ - 'detail' - ] - } - }; - - expect(dereferenceDocument.components.schemas).to.deep.equal(expectedResolvedSchema); - - }); - - it('should return the same object if no $ref is present', function () { - - const originalObject = mockApiDocument.info; - const resolvedObject = resolveRef(originalObject, mockApiDocument); - - expect(resolvedObject).to.deep.equal(originalObject); - - }); - - it('should throw an error for unresolved $ref', function () { - - const invalidRefObject = { - '$ref': '#/components/schemas/NonExistent' - }; - - expect(() => { - - return resolveRef(invalidRefObject, mockApiDocument); - - }).to.throw(); - - }); - -}); diff --git a/test/utilsTests/setupSpectral.test.js b/test/utilsTests/setupSpectral.test.js deleted file mode 100644 index 4fe098d..0000000 --- a/test/utilsTests/setupSpectral.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import pkg from '@stoplight/spectral-core'; -const { Spectral } = pkg; - -import setupSpectral from '../utils/setupSpectral.js'; -import { truthy } from '@stoplight/spectral-functions'; - -describe('setupSpectral Utils:', function () { - - let ruleset; - - before(function () { - - - process.env.LOG_DEBUG = false; - process.env.DEBUG_DEBUG = false; - process.env.INFO_DEBUG = false; - - ruleset = { - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - }, - 'rule-two': { - description: 'Second Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - }; - - }); - - it('should return a Spectral instance with a provided ruleset', function () { - - const spectral = setupSpectral(ruleset); - expect(spectral).to.be.instanceof(Spectral); - expect(Object.keys(spectral.ruleset.rules)).to.deep.equal(['rule-one', 'rule-two']); - - }); - - it('should disable all rules by default', function () { - - const spectral = setupSpectral(ruleset); - expect(spectral.ruleset.rules['rule-one'].enabled).to.be.false; - expect(spectral.ruleset.rules['rule-two'].enabled).to.be.false; - - }); - -}); diff --git a/test/utilsTests/setupSpectralBeforeEach.test.js b/test/utilsTests/setupSpectralBeforeEach.test.js deleted file mode 100644 index 74745c8..0000000 --- a/test/utilsTests/setupSpectralBeforeEach.test.js +++ /dev/null @@ -1,57 +0,0 @@ -import sinon from 'sinon'; -import { truthy } from '@stoplight/spectral-functions'; -import { setupSpectralBeforeEach } from '../utils/setupSpectralBeforeEach.js'; - -describe('setupSpectralBeforeEach Utils:', function () { - - let mockSetupSpectral; - let ruleset; - - beforeEach(function () { - - mockSetupSpectral = sinon.stub().returns({ - setRuleset: sinon.stub(), - ruleset: { - rules: { - 'rule-one': { - description: 'First Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - }, - 'rule-two': { - description: 'Second Rule description', - message: 'Error Message', - severity: 'error', - given: '$', - then: { - function: truthy - } - } - } - } - }); - - }); - - afterEach(function () { - - sinon.restore(); - - }); - - it('should setupSpectral instance and make it available in the test context', function () { - - const beforeEachFunction = setupSpectralBeforeEach(ruleset, 'rule-one', mockSetupSpectral); - const testContext = { }; - - beforeEachFunction.call(testContext); - expect(testContext.spectral).to.exist; - expect(mockSetupSpectral.called).to.be.true; - - }); - -});