diff --git a/packages/azure-openapi-validator/autorest/src/index.ts b/packages/azure-openapi-validator/autorest/src/index.ts index ff48ea27d..b49b7894e 100644 --- a/packages/azure-openapi-validator/autorest/src/index.ts +++ b/packages/azure-openapi-validator/autorest/src/index.ts @@ -19,15 +19,17 @@ const cachedFiles = new Map() function convertLintMsgToAutoRestMsg(message:LintResultMessage):Message { // try to extract provider namespace and resource type - const path = message.jsonpath?.[1] === "paths" && message.jsonpath[2] - const pathComponents = typeof path === "string" && path.split("/") - const pathComponentsProviderIndex = pathComponents && pathComponents.indexOf("providers") - const pathComponentsTail = - pathComponentsProviderIndex && pathComponentsProviderIndex >= 0 && pathComponents.slice(pathComponentsProviderIndex + 1) - const pathComponentProviderNamespace = pathComponentsTail && pathComponentsTail[0] - const pathComponentResourceType = pathComponentsTail && pathComponentsTail[1] + const path = message.jsonpath?.[0] === "paths" ? message.jsonpath[1] : undefined + const pathComponents = typeof path === "string" ? path.split("/") : undefined + const pathComponentsProviderIndex = pathComponents ? pathComponents.lastIndexOf("providers") : -1 + const pathComponentsTail = pathComponents && pathComponentsProviderIndex >= 0 ? pathComponents.slice(pathComponentsProviderIndex + 1) : [] + const pathComponentProviderNamespace = pathComponentsTail[0] || "" + + // we can infer the resource type from the path pattern like: "{scope}/providers/MyNamepace/RT1/{rt1Name}/RT2/{rt2Name}" whose pathComponentsTail is ["MyNamespace","RT1","{rt1Name}","RT2","{rt2Name}"] + const pathComponentResourceType = pathComponentsTail && pathComponentsTail.length >= 3 && pathComponentsTail.length % 2 ? pathComponentsTail[pathComponentsTail.length -2] : "" + const type = message.message.startsWith("[Verbose]this is a verbose message to indicate that this rule was passed for specific swagger schema successfully and no fix is needed") ? "verbose" : message.type const msg = { - Channel: message.type, + Channel: type, Text: message.message, Key: [message.code], Source: [ diff --git a/packages/rulesets/generated/spectral/az-arm.js b/packages/rulesets/generated/spectral/az-arm.js index d2aeb4fa1..ced6b74a8 100644 --- a/packages/rulesets/generated/spectral/az-arm.js +++ b/packages/rulesets/generated/spectral/az-arm.js @@ -329,6 +329,18 @@ function isSchemaEqual(a, b) { } return false; } +function createRuleFunctionWithPasses(fn) { + return (input, options, ctx) => { + const messsages = fn(input, options, ctx); + if (messsages.length === 0) { + messsages.push({ + message: `[Verbose]this is a verbose message to indicate that this rule was passed for specific swagger schema successfully and no fix is needed, please ignore it.`, + path: ctx.path + }); + } + return messsages; + }; +} const nextLinkPropertyMustExist = (opt, _opts, ctx) => { var _a, _b, _c; @@ -1405,7 +1417,7 @@ const bodyParamRepeatedInfo = (pathItem, _opts, paths) => { return errors; }; -function camelCase(propertyName, options, { path }) { +const camelCase = createRuleFunctionWithPasses((propertyName, options, { path }) => { if (!propertyName) { return []; } @@ -1413,12 +1425,12 @@ function camelCase(propertyName, options, { path }) { const camelCaseReg = /^[a-z0-9$-]+([A-Z]{1,3}[a-z0-9$-]+)+$|^[a-z0-9$-]+$|^[a-z0-9$-]+([A-Z]{1,3}[a-z0-9$-]+)*[A-Z]{1,3}$/; if (!camelCaseReg.test(propertyName)) { errors.push({ - message: "", + message: "Property name should be camel case.", path }); } return errors; -} +}); const collectionObjectPropertiesNaming = (op, _opts, paths) => { var _a, _b; @@ -1734,7 +1746,7 @@ const pathBodyParameters = (parameters, _opts, paths) => { return errors; }; -const pathSegmentCasing = (apiPaths, _opts, paths) => { +const pathSegmentCasing = (apiPaths, _opts, { path }) => { if (apiPaths === null || typeof apiPaths !== 'object') { return []; } @@ -1742,7 +1754,6 @@ const pathSegmentCasing = (apiPaths, _opts, paths) => { return []; } const segments = _opts.segments; - const path = paths.path || []; const errors = []; for (const apiPath of Object.keys(apiPaths)) { segments.forEach((seg) => { @@ -2343,7 +2354,7 @@ const ruleset = { }, DefinitionsPropertiesNamesCamelCase: { description: "Property names should be camel case.", - message: "Property name should be camel case.", + message: "{{error}}", severity: "error", resolved: false, given: "$.definitions..[?(@property === 'type' && @ === 'object')]^.properties[?(@property.match(/^[^@].+$/))]~", diff --git a/packages/rulesets/src/spectral/az-arm.ts b/packages/rulesets/src/spectral/az-arm.ts index bb9e54fe5..2af1bf53b 100644 --- a/packages/rulesets/src/spectral/az-arm.ts +++ b/packages/rulesets/src/spectral/az-arm.ts @@ -409,7 +409,7 @@ const ruleset: any = { // this rule covers BodyPropertiesNamesCamelCase and DefinitionsPropertiesNamesCamelCase DefinitionsPropertiesNamesCamelCase: { description: "Property names should be camel case.", - message: "Property name should be camel case.", + message: "{{error}}", severity: "error", resolved: false, given: "$.definitions..[?(@property === 'type' && @ === 'object')]^.properties[?(@property.match(/^[^@].+$/))]~", diff --git a/packages/rulesets/src/spectral/functions/camel-case.ts b/packages/rulesets/src/spectral/functions/camel-case.ts index 0d6a1ac3d..4b797cc3e 100644 --- a/packages/rulesets/src/spectral/functions/camel-case.ts +++ b/packages/rulesets/src/spectral/functions/camel-case.ts @@ -1,8 +1,9 @@ import type { IFunctionResult } from "@stoplight/spectral-core" import type { JsonPath } from "@stoplight/types" +import { createRuleFunctionWithPasses } from "./utils" // check if given propertyName is camel case -export function camelCase(propertyName: string, options: any, { path }: { path: JsonPath }): IFunctionResult[] { +export const camelCase = createRuleFunctionWithPasses((propertyName: string, options: any, { path }: { path: JsonPath }): IFunctionResult[] => { if (!propertyName) { return [] as IFunctionResult[] } @@ -12,11 +13,11 @@ export function camelCase(propertyName: string, options: any, { path }: { path: if (!camelCaseReg.test(propertyName)) { errors.push({ - message:"", + message: "Property name should be camel case.", path }) } return errors -} +}) export default camelCase \ No newline at end of file diff --git a/packages/rulesets/src/spectral/functions/path-segment-casing.ts b/packages/rulesets/src/spectral/functions/path-segment-casing.ts index 2d8d9dae0..4ce4969eb 100644 --- a/packages/rulesets/src/spectral/functions/path-segment-casing.ts +++ b/packages/rulesets/src/spectral/functions/path-segment-casing.ts @@ -1,5 +1,5 @@ // _opts has a property 'segments' as string[] to specify the segment names to check for -export const pathSegmentCasing = (apiPaths:any, _opts:any, paths: any) => { +export const pathSegmentCasing = (apiPaths:any, _opts:any, {path}: any) => { if (apiPaths === null || typeof apiPaths !== 'object') { return []; } @@ -8,8 +8,6 @@ export const pathSegmentCasing = (apiPaths:any, _opts:any, paths: any) => { return [] } const segments = _opts.segments - const path = paths.path || []; - const errors:any[] = []; for (const apiPath of Object.keys(apiPaths)) { segments.forEach((seg:string) => { diff --git a/packages/rulesets/src/spectral/functions/utils.ts b/packages/rulesets/src/spectral/functions/utils.ts index 8e4756da6..b65603279 100644 --- a/packages/rulesets/src/spectral/functions/utils.ts +++ b/packages/rulesets/src/spectral/functions/utils.ts @@ -1,3 +1,5 @@ +import { IFunctionResult, RulesetFunctionContext } from "@stoplight/spectral-core" + /** * get all properties as array */ @@ -174,3 +176,16 @@ export function isSchemaEqual(a: any, b: any): boolean { } return false; } + +export function createRuleFunctionWithPasses(fn:(input:I, options:O, ctx: RulesetFunctionContext)=> IFunctionResult[]) { + return (input:I, options:O, ctx: RulesetFunctionContext):IFunctionResult[] => { + const messsages = fn(input,options,ctx) + if (messsages.length === 0) { + messsages.push({ + message: `[Verbose]this is a verbose message to indicate that this rule was passed for specific swagger schema successfully and no fix is needed, please ignore it.`, + path: ctx.path + }) + } + return messsages + } +} \ No newline at end of file