Error serializer. (#269)
* Resolve nested Schema Objects * npm run cli * errors. * Error serialization * simplify initialization. * minor
This commit is contained in:
Родитель
bc0c5a3e8e
Коммит
5bfc9951a1
|
@ -1,3 +1,6 @@
|
|||
### 07/05/2018 0.4.56
|
||||
- Error serialization.
|
||||
|
||||
### 07/05/2018 0.4.55
|
||||
- Remove a dependency on `@types/winston` package. `winston` is updated to `3.0.0`.
|
||||
|
||||
|
|
|
@ -47,8 +47,9 @@ export interface Message {
|
|||
/**
|
||||
* Returns a promise with the examples validation of the swagger.
|
||||
*/
|
||||
async function analyzeSwagger(swaggerFileName: string, autoRestApi: extensionBase.Host)
|
||||
: Promise<void> {
|
||||
async function analyzeSwagger(
|
||||
swaggerFileName: string, autoRestApi: extensionBase.Host
|
||||
): Promise<void> {
|
||||
const swaggerFile = await autoRestApi.ReadFile(swaggerFileName)
|
||||
const swagger = yaml.safeLoad(swaggerFile)
|
||||
const exampleValidationResults = await openApiValidationExample(swagger, swaggerFileName)
|
||||
|
@ -78,8 +79,8 @@ export interface Options extends specValidator.Options {
|
|||
}
|
||||
|
||||
export async function openApiValidationExample(
|
||||
swagger: yaml.DocumentLoadResult, swaggerFileName: string, options?: Options)
|
||||
: Promise<Message[]> {
|
||||
swagger: yaml.DocumentLoadResult, swaggerFileName: string, options?: Options
|
||||
): Promise<Message[]> {
|
||||
const formattedResult: FormattedOutput[] = []
|
||||
if (!options) { options = {} }
|
||||
options.consoleLogLevel = "off"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
// import util = require('util')
|
||||
import { log } from "../util/logging"
|
||||
import * as validate from "../validate"
|
||||
import * as yargs from "yargs"
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
* validation happened. This will help find the problematic information in the
|
||||
* spec and will be useful in preparing report.
|
||||
*
|
||||
* @member {string} apiVersion Describes the api-version of the openapi
|
||||
* specification. This will help find the openapi spec corresponding to that
|
||||
* @member {string} apiVersion Describes the api-version of the OpenAPI
|
||||
* specification. This will help find the OpenAPI spec corresponding to that
|
||||
* api-version and will be useful in preparing report.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* @member {boolean} [successfulRequest] Describes the status of live request
|
||||
* validation.
|
||||
*
|
||||
* @member {array} [operationInfo] The corresponding operation(s) in openapi
|
||||
* @member {array} [operationInfo] The corresponding operation(s) in OpenAPI
|
||||
* spec that was used for validating the request.
|
||||
*
|
||||
* @member {array} [errors] Provides more information about live response
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* @member {boolean} [successfulResponse] Describes the status of live response
|
||||
* validation.
|
||||
*
|
||||
* @member {array} [operationInfo] The corresponding operation(s) in openapi
|
||||
* @member {array} [operationInfo] The corresponding operation(s) in OpenAPI
|
||||
* spec that was used for validating the response.
|
||||
*
|
||||
* @member {array} [errors] Provides more information about live response
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* status of live request validation.
|
||||
*
|
||||
* @member {array} [requestValidationResult.operationInfo] The corresponding
|
||||
* operation(s) in openapi spec that was used for validating the request.
|
||||
* operation(s) in OpenAPI spec that was used for validating the request.
|
||||
*
|
||||
* @member {array} [requestValidationResult.errors] Provides more information
|
||||
* about live response validation.
|
||||
|
|
|
@ -93,7 +93,7 @@ ${this.getRequestBody()}
|
|||
return requestTemplate
|
||||
}
|
||||
|
||||
private populateResponse(response: Response, responseType: string) {
|
||||
private populateResponse(response: Response, responseType: string): string {
|
||||
if (!responseType) { responseType = "Response" }
|
||||
const responseGuid = uuid.v4()
|
||||
const responseTemplate = `
|
||||
|
@ -121,7 +121,7 @@ ${this.getResponseBody(response)}
|
|||
return responseTemplate
|
||||
}
|
||||
|
||||
private populateCurl() {
|
||||
private populateCurl(): string {
|
||||
const method = this.request.method
|
||||
const url = this.request.url
|
||||
const requestHeaders = this.getCurlRequestHeaders()
|
||||
|
|
|
@ -115,8 +115,9 @@ export class UmlGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private getPropertyType(modelName: Unknown, property: SchemaObject, references: string[])
|
||||
: string {
|
||||
private getPropertyType(
|
||||
modelName: Unknown, property: SchemaObject, references: string[]
|
||||
): string {
|
||||
|
||||
const type = property.type
|
||||
switch (type) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { objectPathAppend } from "./objectPath"
|
||||
import { Tracked, tracked } from "./tracked"
|
||||
|
||||
export function arrayMap<T>(array: Tracked<T[]>, f: (value: Tracked<T>) => T) {
|
||||
export function arrayMap<T>(array: Tracked<T[]>, f: (value: Tracked<T>) => T): T[] {
|
||||
const path = array.path
|
||||
const value = array.value
|
||||
let same = true
|
||||
|
|
|
@ -14,9 +14,3 @@ export function entryName<T>(e: Entry<T>): string {
|
|||
export function entryValue<T>(e: Entry<T>): T {
|
||||
return e[1]
|
||||
}
|
||||
|
||||
/*
|
||||
export function entryMap<T>(e: Entry<T>, f: (value: T, name: string) => T): Entry<T> {
|
||||
return entry(entryName(e), f(entryValue(e), entryName(e)))
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { Unknown } from "./unknown"
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
|
|
|
@ -18,9 +18,8 @@ export type PropertySetTransformation<T> = {
|
|||
/**
|
||||
* Clones the given `propertySet` and transforms its properties according to the given
|
||||
* `propertyTransformations`.
|
||||
* @param propertySet must be a pure data object with properties.
|
||||
* @param propertySet must be a tracked object of a pure data object with properties.
|
||||
* @param propertySetTransformation
|
||||
* @param path
|
||||
* @returns a new object with transformed properties.
|
||||
*/
|
||||
export function propertySetMap<T>(
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
export const enum Severity {
|
||||
Critical = 0,
|
||||
Error = 1,
|
||||
Warning = 2,
|
||||
Information = 3,
|
||||
Verbose = 4
|
||||
}
|
|
@ -10,7 +10,8 @@ export interface StringMap<T> {
|
|||
}
|
||||
|
||||
export function stringMapForEach<T>(
|
||||
src: Tracked<StringMap<T>>, f: (value: Tracked<NonUndefined<T>>) => void): void {
|
||||
src: Tracked<StringMap<T>>, f: (value: Tracked<NonUndefined<T>>) => void
|
||||
): void {
|
||||
const sv = src.value
|
||||
for (const name in sv) {
|
||||
const value = sv[name]
|
||||
|
|
|
@ -172,7 +172,8 @@ export function makeRequest(options: Options): Promise<SwaggerObject> {
|
|||
* @return A chain of resolved or rejected promises
|
||||
*/
|
||||
export async function executePromisesSequentially(
|
||||
promiseFactories: Array<() => Promise<void>>): Promise<void> {
|
||||
promiseFactories: Array<() => Promise<void>>
|
||||
): Promise<void> {
|
||||
for (const promiseFactory of promiseFactories) {
|
||||
await promiseFactory()
|
||||
}
|
||||
|
@ -296,7 +297,7 @@ export function joinPath(...args: string[]): string {
|
|||
*
|
||||
* @returns {object} jsonDoc - Parsed document in JSON format.
|
||||
*/
|
||||
export function parseJsonWithPathFragments(...args: string[]) {
|
||||
export function parseJsonWithPathFragments(...args: string[]): Promise<SwaggerObject> {
|
||||
const specPath = joinPath(...args)
|
||||
return parseJson(specPath)
|
||||
}
|
||||
|
@ -391,7 +392,7 @@ export function setObject(doc: {}, ptr: string, value: any) {
|
|||
*
|
||||
* @param {string} ptr The json reference pointer.
|
||||
*/
|
||||
export function removeObject(doc: {}, ptr: string) {
|
||||
function removeObject(doc: {}, ptr: string) {
|
||||
let result
|
||||
try {
|
||||
result = jsonPointer.remove(doc, ptr)
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
import { Severity } from "./severity"
|
||||
|
||||
/**
|
||||
* @class
|
||||
* Error that results from validations.
|
||||
*/
|
||||
export class ValidationError {
|
||||
/**
|
||||
*
|
||||
* @param name Validation Error Name
|
||||
* @param severity The
|
||||
*/
|
||||
constructor(
|
||||
public readonly name: string,
|
||||
public readonly severity: Severity
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
export const errorConstants: Map<string, ValidationError> = new Map<string, ValidationError>([
|
||||
validationErrorEntry("INVALID_TYPE", Severity.Critical),
|
||||
validationErrorEntry("INVALID_FORMAT", Severity.Critical),
|
||||
validationErrorEntry("ENUM_MISMATCH", Severity.Critical),
|
||||
validationErrorEntry("ENUM_CASE_MISMATCH", Severity.Error),
|
||||
validationErrorEntry("PII_MISMATCH", Severity.Warning),
|
||||
validationErrorEntry("ANY_OF_MISSING", Severity.Critical),
|
||||
validationErrorEntry("ONE_OF_MISSING", Severity.Critical),
|
||||
validationErrorEntry("ONE_OF_MULTIPLE", Severity.Critical),
|
||||
validationErrorEntry("NOT_PASSED", Severity.Critical),
|
||||
// arrays
|
||||
validationErrorEntry("ARRAY_LENGTH_SHORT", Severity.Critical),
|
||||
validationErrorEntry("ARRAY_LENGTH_LONG", Severity.Critical),
|
||||
validationErrorEntry("ARRAY_UNIQUE", Severity.Critical),
|
||||
validationErrorEntry("ARRAY_ADDITIONAL_ITEMS", Severity.Critical),
|
||||
// numeric
|
||||
validationErrorEntry("MULTIPLE_OF", Severity.Critical),
|
||||
validationErrorEntry("MINIMUM", Severity.Critical),
|
||||
validationErrorEntry("MINIMUM_EXCLUSIVE", Severity.Critical),
|
||||
validationErrorEntry("MAXIMUM", Severity.Critical),
|
||||
validationErrorEntry("MAXIMUM_EXCLUSIVE", Severity.Critical),
|
||||
// objects
|
||||
validationErrorEntry("OBJECT_PROPERTIES_MINIMUM", Severity.Critical),
|
||||
validationErrorEntry("OBJECT_PROPERTIES_MAXIMUM", Severity.Critical),
|
||||
validationErrorEntry("OBJECT_MISSING_REQUIRED_PROPERTY", Severity.Critical),
|
||||
validationErrorEntry("OBJECT_ADDITIONAL_PROPERTIES", Severity.Critical),
|
||||
validationErrorEntry("OBJECT_DEPENDENCY_KEY", Severity.Warning),
|
||||
// string
|
||||
validationErrorEntry("MIN_LENGTH", Severity.Critical),
|
||||
validationErrorEntry("MAX_LENGTH", Severity.Critical),
|
||||
validationErrorEntry("PATTERN", Severity.Critical),
|
||||
// operation
|
||||
validationErrorEntry("OPERATION_NOT_FOUND_IN_CACHE", Severity.Critical),
|
||||
validationErrorEntry("OPERATION_NOT_FOUND_IN_CACHE_WITH_VERB", Severity.Critical),
|
||||
validationErrorEntry("OPERATION_NOT_FOUND_IN_CACHE_WITH_API", Severity.Critical),
|
||||
validationErrorEntry("OPERATION_NOT_FOUND_IN_CACHE_WITH_PROVIDER", Severity.Critical),
|
||||
validationErrorEntry("MULTIPLE_OPERATIONS_FOUND", Severity.Critical),
|
||||
// others
|
||||
validationErrorEntry("INVALID_RESPONSE_HEADER", Severity.Critical),
|
||||
validationErrorEntry("INVALID_RESPONSE_CODE", Severity.Critical),
|
||||
validationErrorEntry("INVALID_RESPONSE_BODY", Severity.Critical),
|
||||
validationErrorEntry("INVALID_REQUEST_PARAMETER", Severity.Critical),
|
||||
validationErrorEntry("INVALID_CONTENT_TYPE", Severity.Error),
|
||||
])
|
||||
|
||||
/**
|
||||
* Gets the severity from an error code. If the code is unknown assume critical.
|
||||
*/
|
||||
export function errorCodeToSeverity(code: string): Severity {
|
||||
const errorConstant = errorConstants.get(code)
|
||||
return errorConstant ? errorConstant.severity : Severity.Critical
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes validation results into a flat array.
|
||||
*/
|
||||
export function processValidationErrors(rawValidation: any): any {
|
||||
const requestSerializedErrors: any[] = []
|
||||
const responseSerializedErrors: any[] = []
|
||||
|
||||
serializeErrors(
|
||||
rawValidation.requestValidationResult,
|
||||
requestSerializedErrors,
|
||||
[]
|
||||
)
|
||||
serializeErrors(
|
||||
rawValidation.responseValidationResult,
|
||||
responseSerializedErrors,
|
||||
[]
|
||||
)
|
||||
|
||||
rawValidation.requestValidationResult.errors = requestSerializedErrors
|
||||
rawValidation.responseValidationResult.errors = responseSerializedErrors
|
||||
|
||||
return rawValidation
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes error tree
|
||||
*/
|
||||
export function serializeErrors(node: any, serializedErrors: any, path: any) {
|
||||
if (isLeaf(node)) {
|
||||
if (isTrueError(node)) {
|
||||
if (node.path) {
|
||||
node.path = consolidatePath(path, node.path).join("/")
|
||||
}
|
||||
serializedErrors.push(node)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (node.path) {
|
||||
// in this case the path will be set to the url instead of the path to the property
|
||||
if (node.code === "INVALID_REQUEST_PARAMETER" && node.in === "body") {
|
||||
node.path = []
|
||||
} else if (
|
||||
(node.in === "query" || node.in === "path") &&
|
||||
node.path[0] === "paths" &&
|
||||
node.name
|
||||
) {
|
||||
// in this case we will want to normalize the path with the uri and the paramter name
|
||||
node.path = [node.path[1], node.name]
|
||||
}
|
||||
path = consolidatePath(path, node.path)
|
||||
}
|
||||
if (node.errors) {
|
||||
node.errors.map((validationError: any) => {
|
||||
serializeErrors(validationError, serializedErrors, path);
|
||||
})
|
||||
}
|
||||
|
||||
if (node.inner) {
|
||||
node.inner.map((validationError: any) => {
|
||||
serializeErrors(validationError, serializedErrors, path)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function validationErrorEntry(id: string, severity: Severity): [string, ValidationError] {
|
||||
return [id, new ValidationError(id, severity)]
|
||||
}
|
||||
|
||||
function isTrueError(node: any) {
|
||||
// this is necessary to filter out extra errors coming from doing the ONE_OF transformation on
|
||||
// the models to allow "null"
|
||||
if (
|
||||
node.code === "INVALID_TYPE" &&
|
||||
node.params &&
|
||||
node.params[0] === "null"
|
||||
) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function isLeaf(node: any) {
|
||||
return !node.errors && !node.inner;
|
||||
};
|
||||
|
||||
function consolidatePath(path: any, suffixPath: any) {
|
||||
let newSuffixIndex = 0
|
||||
let overlapIndex = path.lastIndexOf(suffixPath[newSuffixIndex])
|
||||
let previousIndex = overlapIndex
|
||||
|
||||
if (overlapIndex === -1) {
|
||||
return path.concat(suffixPath)
|
||||
}
|
||||
|
||||
for (
|
||||
newSuffixIndex = 1;
|
||||
newSuffixIndex < suffixPath.length;
|
||||
++newSuffixIndex
|
||||
) {
|
||||
previousIndex = overlapIndex
|
||||
overlapIndex = path.lastIndexOf(suffixPath[newSuffixIndex])
|
||||
if (overlapIndex === -1 || overlapIndex !== previousIndex + 1) {
|
||||
break
|
||||
}
|
||||
}
|
||||
let newPath = []
|
||||
if (newSuffixIndex === suffixPath.length) {
|
||||
// if all elements are contained in the existing path, nothing to do.
|
||||
newPath = path.slice(0)
|
||||
} else if (overlapIndex === -1 && previousIndex === path.length - 1) {
|
||||
// if we didn't find element at x in the previous path and element at x -1 is the last one in
|
||||
// the path, append everything from x
|
||||
newPath = path.concat(suffixPath.slice(newSuffixIndex))
|
||||
} else {
|
||||
// otherwise it is not contained at all, so concat everything.
|
||||
newPath = path.concat(suffixPath)
|
||||
}
|
||||
|
||||
return newPath
|
||||
}
|
|
@ -43,8 +43,8 @@ export class ValidateResponse {
|
|||
}
|
||||
|
||||
public constructErrors(
|
||||
validationError: Error, specPath: Unknown, providerNamespace: Unknown): ValidationError[] {
|
||||
const self = this
|
||||
validationError: Error, specPath: Unknown, providerNamespace: Unknown
|
||||
): ValidationError[] {
|
||||
if (!validationError) {
|
||||
throw new Error("validationError cannot be null or undefined.")
|
||||
}
|
||||
|
@ -56,14 +56,14 @@ export class ValidateResponse {
|
|||
type: "error",
|
||||
inner: error.inner
|
||||
}
|
||||
if (error.code && self.mapper[error.code]) {
|
||||
if (error.code && this.mapper[error.code]) {
|
||||
e.code = error.code
|
||||
e.id = self.mapper[error.code]
|
||||
e.id = this.mapper[error.code]
|
||||
e.message = error.message
|
||||
} else {
|
||||
e.code = "SWAGGER_SCHEMA_VALIDATION_ERROR"
|
||||
e.message = validationError.message
|
||||
e.id = self.mapper[e.code]
|
||||
e.id = this.mapper[e.code]
|
||||
e.inner = error
|
||||
}
|
||||
if (error.path && error.path.length) {
|
||||
|
|
|
@ -21,8 +21,9 @@ export const finalValidationResult: FinalValidationResult = {
|
|||
validityStatus: true
|
||||
}
|
||||
|
||||
export async function getDocumentsFromCompositeSwagger(compositeSpecPath: string)
|
||||
: Promise<string[]> {
|
||||
export async function getDocumentsFromCompositeSwagger(
|
||||
compositeSpecPath: string
|
||||
): Promise<string[]> {
|
||||
try {
|
||||
const compositeSwagger = await utils.parseJson(compositeSpecPath)
|
||||
if (!(compositeSwagger.documents
|
||||
|
@ -54,8 +55,9 @@ export async function getDocumentsFromCompositeSwagger(compositeSpecPath: string
|
|||
}
|
||||
}
|
||||
|
||||
export async function validateSpec(specPath: string, options: Options|undefined)
|
||||
: Promise<SpecValidationResult> {
|
||||
export async function validateSpec(
|
||||
specPath: string, options: Options|undefined
|
||||
): Promise<SpecValidationResult> {
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
log.filepath = options.logFilepath || log.filepath
|
||||
|
@ -88,8 +90,9 @@ export async function validateSpec(specPath: string, options: Options|undefined)
|
|||
}
|
||||
}
|
||||
|
||||
export async function validateCompositeSpec(compositeSpecPath: string, options: Options)
|
||||
: Promise<void> {
|
||||
export async function validateCompositeSpec(
|
||||
compositeSpecPath: string, options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -107,8 +110,8 @@ export async function validateCompositeSpec(compositeSpecPath: string, options:
|
|||
}
|
||||
|
||||
export async function validateExamples(
|
||||
specPath: string, operationIds: string|undefined, options?: Options)
|
||||
: Promise<SpecValidationResult> {
|
||||
specPath: string, operationIds: string|undefined, options?: Options
|
||||
): Promise<SpecValidationResult> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -128,8 +131,9 @@ export async function validateExamples(
|
|||
}
|
||||
}
|
||||
|
||||
export async function validateExamplesInCompositeSpec(compositeSpecPath: string, options: Options)
|
||||
: Promise<void> {
|
||||
export async function validateExamplesInCompositeSpec(
|
||||
compositeSpecPath: string, options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -152,8 +156,9 @@ export interface Options extends specResolver.Options, umlGeneratorLib.Options {
|
|||
logFilepath?: Unknown
|
||||
}
|
||||
|
||||
export async function resolveSpec(specPath: string, outputDir: string, options: Options)
|
||||
: Promise<void> {
|
||||
export async function resolveSpec(
|
||||
specPath: string, outputDir: string, options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -176,8 +181,9 @@ export async function resolveSpec(specPath: string, outputDir: string, options:
|
|||
}
|
||||
}
|
||||
|
||||
export async function resolveCompositeSpec(specPath: string, outputDir: string, options: Options)
|
||||
: Promise<void> {
|
||||
export async function resolveCompositeSpec(
|
||||
specPath: string, outputDir: string, options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -199,8 +205,8 @@ export async function generateWireFormat(
|
|||
outDir: Unknown,
|
||||
emitYaml: Unknown,
|
||||
operationIds: string|null,
|
||||
options: Options)
|
||||
: Promise<void> {
|
||||
options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -217,7 +223,8 @@ export async function generateWireFormat(
|
|||
}
|
||||
|
||||
export async function generateWireFormatInCompositeSpec(
|
||||
compositeSpecPath: string, outDir: Unknown, emitYaml: Unknown, options: Options): Promise<void> {
|
||||
compositeSpecPath: string, outDir: Unknown, emitYaml: Unknown, options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -235,8 +242,9 @@ export async function generateWireFormatInCompositeSpec(
|
|||
}
|
||||
}
|
||||
|
||||
export async function generateUml(specPath: string, outputDir: string, options?: Options)
|
||||
: Promise<void> {
|
||||
export async function generateUml(
|
||||
specPath: string, outputDir: string, options?: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
@ -293,8 +301,9 @@ export function logDetailedInfo(validator: SpecValidator): void {
|
|||
log.silly("----------------------------")
|
||||
}
|
||||
|
||||
export function extractXMsExamples(specPath: string, recordings: Unknown, options: Options)
|
||||
: Promise<void> {
|
||||
export function extractXMsExamples(
|
||||
specPath: string, recordings: Unknown, options: Options
|
||||
): Promise<void> {
|
||||
|
||||
if (!options) { options = {} }
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
|
||||
|
|
|
@ -210,8 +210,9 @@ export class LiveValidator {
|
|||
*
|
||||
* @returns {PotentialOperationsResult} Potential operation result object.
|
||||
*/
|
||||
public getPotentialOperations(requestUrl: string, requestMethod: string)
|
||||
: PotentialOperationsResult {
|
||||
public getPotentialOperations(
|
||||
requestUrl: string, requestMethod: string
|
||||
): PotentialOperationsResult {
|
||||
|
||||
if (_.isEmpty(this.cache)) {
|
||||
const msgStr =
|
||||
|
@ -236,7 +237,6 @@ export class LiveValidator {
|
|||
'requestMethod is a required parameter of type "string" and it cannot be an empty string.')
|
||||
}
|
||||
|
||||
const self = this
|
||||
let potentialOperations: Operation[] = []
|
||||
const parsedUrl = url.parse(requestUrl, true)
|
||||
const pathStr = parsedUrl.pathname
|
||||
|
@ -267,7 +267,7 @@ export class LiveValidator {
|
|||
provider = provider.toLowerCase()
|
||||
|
||||
// Search using provider
|
||||
const allApiVersions = self.cache[provider]
|
||||
const allApiVersions = this.cache[provider]
|
||||
if (allApiVersions) {
|
||||
// Search using api-version found in the requestUrl
|
||||
if (apiVersion) {
|
||||
|
@ -277,7 +277,7 @@ export class LiveValidator {
|
|||
// Search using requestMethod provided by user
|
||||
if (operationsForHttpMethod) {
|
||||
// Find the best match using regex on path
|
||||
potentialOperations = self.getPotentialOperationsHelper(
|
||||
potentialOperations = this.getPotentialOperationsHelper(
|
||||
pathStr, requestMethod, operationsForHttpMethod)
|
||||
// If potentialOperations were to be [] then we need reason
|
||||
msg =
|
||||
|
@ -297,7 +297,7 @@ export class LiveValidator {
|
|||
`in the cache.`
|
||||
code = C.ErrorCodes.OperationNotFoundInCacheWithApi
|
||||
log.debug(`${msg} We'll search in the resource provider "Microsoft.Unknown".`)
|
||||
potentialOperations = self.getPotentialOperationsHelper(pathStr, requestMethod, [])
|
||||
potentialOperations = this.getPotentialOperationsHelper(pathStr, requestMethod, [])
|
||||
}
|
||||
} else {
|
||||
msg = `Could not find api-version in requestUrl "${requestUrl}".`
|
||||
|
@ -309,7 +309,7 @@ export class LiveValidator {
|
|||
msg = `Could not find provider "${provider}" in the cache.`
|
||||
code = C.ErrorCodes.OperationNotFoundInCacheWithProvider
|
||||
log.debug(`${msg} We'll search in the resource provider "Microsoft.Unknown".`)
|
||||
potentialOperations = self.getPotentialOperationsHelper(pathStr, requestMethod, [])
|
||||
potentialOperations = this.getPotentialOperationsHelper(pathStr, requestMethod, [])
|
||||
}
|
||||
|
||||
// Provide reason when we do not find any potential operation in cache
|
||||
|
@ -330,7 +330,6 @@ export class LiveValidator {
|
|||
* @returns {object} validationResult - Validation result for given input
|
||||
*/
|
||||
public validateLiveRequestResponse(requestResponseObj: RequestResponseObj): ValidationResult {
|
||||
const self = this
|
||||
const validationResult: ValidationResult = {
|
||||
requestValidationResult: {
|
||||
successfulRequest: false,
|
||||
|
@ -378,7 +377,7 @@ export class LiveValidator {
|
|||
let potentialOperationsResult
|
||||
let potentialOperations: Operation[] = []
|
||||
try {
|
||||
potentialOperationsResult = self.getPotentialOperations(request.url, request.method)
|
||||
potentialOperationsResult = this.getPotentialOperations(request.url, request.method)
|
||||
potentialOperations = potentialOperationsResult.operations
|
||||
} catch (err) {
|
||||
const msg =
|
||||
|
@ -472,7 +471,8 @@ export class LiveValidator {
|
|||
* @returns {Array<Operation>} List of potential operations matching the requestPath.
|
||||
*/
|
||||
private getPotentialOperationsHelper(
|
||||
requestPath: string, requestMethod: string, operations: Operation[]): Operation[] {
|
||||
requestPath: string, requestMethod: string, operations: Operation[]
|
||||
): Operation[] {
|
||||
if (requestPath === null
|
||||
|| requestPath === undefined
|
||||
|| typeof requestPath.valueOf() !== "string"
|
||||
|
@ -493,7 +493,6 @@ export class LiveValidator {
|
|||
throw new Error('operations is a required parameter of type "array".')
|
||||
}
|
||||
|
||||
const self = this
|
||||
let potentialOperations = operations.filter(operation => {
|
||||
const pathObject = operation.pathObject as PathObject
|
||||
const pathMatch = pathObject.regexp.exec(requestPath)
|
||||
|
@ -503,9 +502,9 @@ export class LiveValidator {
|
|||
// If we do not find any match then we'll look into Microsoft.Unknown -> unknown-api-version
|
||||
// for given requestMethod as the fall back option
|
||||
if (!potentialOperations.length) {
|
||||
if (self.cache[C.unknownResourceProvider] &&
|
||||
self.cache[C.unknownResourceProvider][C.unknownApiVersion]) {
|
||||
operations = self.cache[C.unknownResourceProvider][C.unknownApiVersion][requestMethod]
|
||||
if (this.cache[C.unknownResourceProvider] &&
|
||||
this.cache[C.unknownResourceProvider][C.unknownApiVersion]) {
|
||||
operations = this.cache[C.unknownResourceProvider][C.unknownApiVersion][requestMethod]
|
||||
potentialOperations = operations.filter(operation => {
|
||||
const pathObject = operation.pathObject as PathObject
|
||||
let pathTemplate = pathObject.path
|
||||
|
|
|
@ -229,8 +229,9 @@ export class SpecResolver {
|
|||
*
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
private async resolveRelativePaths(doc?: Unknown, docPath?: string, filterType?: string)
|
||||
: Promise<void> {
|
||||
private async resolveRelativePaths(
|
||||
doc?: Unknown, docPath?: string, filterType?: string
|
||||
): Promise<void> {
|
||||
|
||||
let docDir
|
||||
|
||||
|
@ -295,8 +296,8 @@ export class SpecResolver {
|
|||
* @return undefined the modified object
|
||||
*/
|
||||
private async resolveRelativeReference(
|
||||
refName: string, refDetails: RefDetails, doc: Unknown, docPath: string|undefined)
|
||||
: Promise<void> {
|
||||
refName: string, refDetails: RefDetails, doc: Unknown, docPath: string|undefined
|
||||
): Promise<void> {
|
||||
|
||||
if (!refName || (refName && typeof refName.valueOf() !== "string")) {
|
||||
throw new Error('refName cannot be null or undefined and must be of type "string".')
|
||||
|
@ -771,8 +772,9 @@ export class SpecResolver {
|
|||
* [here](https://bit.ly/2sw5MOa)
|
||||
* for detailed structure of the object.
|
||||
*/
|
||||
private updateReferencesWithOneOf(subTreeMap: Map<string, PolymorphicTree>, references: any[])
|
||||
: void {
|
||||
private updateReferencesWithOneOf(
|
||||
subTreeMap: Map<string, PolymorphicTree>, references: any[]
|
||||
): void {
|
||||
|
||||
const spec = this.specInJson
|
||||
|
||||
|
@ -815,8 +817,8 @@ export class SpecResolver {
|
|||
* inheritance chain.
|
||||
*/
|
||||
private createPolymorphicTree(
|
||||
name: string, discriminator: string, subTreeMap: Map<string, PolymorphicTree>)
|
||||
: PolymorphicTree {
|
||||
name: string, discriminator: string, subTreeMap: Map<string, PolymorphicTree>
|
||||
): PolymorphicTree {
|
||||
|
||||
if (name === null
|
||||
|| name === undefined
|
||||
|
|
|
@ -400,8 +400,8 @@ export class SpecValidator {
|
|||
code: ErrorCode,
|
||||
message: string,
|
||||
innerErrors?: null|Error[],
|
||||
skipValidityStatusUpdate?: boolean)
|
||||
: Error {
|
||||
skipValidityStatusUpdate?: boolean
|
||||
): Error {
|
||||
|
||||
const err: Error = {
|
||||
code: code.name,
|
||||
|
@ -457,8 +457,8 @@ export class SpecValidator {
|
|||
}
|
||||
|
||||
private initializeExampleResult(
|
||||
operationId: string, exampleType: string, scenarioName: string|undefined)
|
||||
: void {
|
||||
operationId: string, exampleType: string, scenarioName: string|undefined
|
||||
): void {
|
||||
const initialResult = {
|
||||
isValid: true,
|
||||
request: {
|
||||
|
@ -497,8 +497,8 @@ export class SpecValidator {
|
|||
isValid: Unknown,
|
||||
msg: string,
|
||||
requestValidationErrors?: Error[]|null,
|
||||
requestValidationWarnings?: Unknown)
|
||||
: void {
|
||||
requestValidationWarnings?: Unknown
|
||||
): void {
|
||||
|
||||
if (operationResult.request === undefined) {
|
||||
throw new Error("operationResult.result is undefined")
|
||||
|
@ -527,8 +527,8 @@ export class SpecValidator {
|
|||
isValid: Unknown,
|
||||
msg: string,
|
||||
responseValidationErrors?: Error[]|null,
|
||||
responseValidationWarnings?: Unknown)
|
||||
: void {
|
||||
responseValidationWarnings?: Unknown
|
||||
): void {
|
||||
|
||||
if (operationResult.responses === undefined) {
|
||||
throw new Error("operationResult.responses is undefined")
|
||||
|
@ -558,8 +558,8 @@ export class SpecValidator {
|
|||
requestValidationErrors: Error[],
|
||||
requestValidationWarnings: Unknown[],
|
||||
exampleType: string,
|
||||
scenarioName?: string)
|
||||
: void {
|
||||
scenarioName?: string
|
||||
): void {
|
||||
|
||||
this.initializeExampleResult(operationId, exampleType, scenarioName)
|
||||
let operationResult
|
||||
|
@ -597,8 +597,8 @@ export class SpecValidator {
|
|||
responseValidationErrors: Error[],
|
||||
responseValidationWarnings: Unknown[],
|
||||
exampleType: string,
|
||||
scenarioName?: string)
|
||||
: void {
|
||||
scenarioName?: string
|
||||
): void {
|
||||
|
||||
this.initializeExampleResult(operationId, exampleType, scenarioName)
|
||||
let operationResult
|
||||
|
@ -646,7 +646,8 @@ export class SpecValidator {
|
|||
* @return {object} xmsExample - The xmsExample object.
|
||||
*/
|
||||
private constructOperationResult(
|
||||
operation: Operation, result: ValidationResult, exampleType: string): void {
|
||||
operation: Operation, result: ValidationResult, exampleType: string
|
||||
): void {
|
||||
|
||||
const operationId = operation.operationId
|
||||
if (result.exampleNotFound) {
|
||||
|
@ -779,8 +780,9 @@ export class SpecValidator {
|
|||
*
|
||||
* @return {object} result - The validation result.
|
||||
*/
|
||||
private validateRequest(operation: Operation, exampleParameterValues: { [name: string]: string })
|
||||
: RequestValidation {
|
||||
private validateRequest(
|
||||
operation: Operation, exampleParameterValues: { [name: string]: string }
|
||||
): RequestValidation {
|
||||
|
||||
const self = this
|
||||
if (operation === null || operation === undefined || typeof operation !== "object") {
|
||||
|
@ -1063,7 +1065,8 @@ export class SpecValidator {
|
|||
* @return {object} result - The validation result.
|
||||
*/
|
||||
private validateXmsExampleResponses(
|
||||
operation: Operation, exampleResponseValue: { [name: string]: ExampleResponse }) {
|
||||
operation: Operation, exampleResponseValue: { [name: string]: ExampleResponse }
|
||||
) {
|
||||
|
||||
const self = this
|
||||
const result: any = {}
|
||||
|
|
|
@ -160,7 +160,8 @@ export class WireFormatGenerator {
|
|||
* @return {object} err Return the constructed Error object.
|
||||
*/
|
||||
private constructErrorObject(
|
||||
code: any, message: string, innerErrors: any[], skipValidityStatusUpdate?: boolean) {
|
||||
code: any, message: string, innerErrors: any[], skipValidityStatusUpdate?: boolean
|
||||
) {
|
||||
const err = {
|
||||
code,
|
||||
message,
|
||||
|
@ -196,7 +197,8 @@ export class WireFormatGenerator {
|
|||
}
|
||||
|
||||
private resolveRelativeReference(
|
||||
refName: any, refDetails: any, doc: any, docPath: any): Promise<any> {
|
||||
refName: any, refDetails: any, doc: any, docPath: any
|
||||
): Promise<any> {
|
||||
|
||||
if (!refName || (refName && typeof refName.valueOf() !== "string")) {
|
||||
throw new Error('refName cannot be null or undefined and must be of type "string".')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oav",
|
||||
"version": "0.4.55",
|
||||
"version": "0.4.56",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oav",
|
||||
"version": "0.4.55",
|
||||
"version": "0.4.56",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation",
|
||||
"email": "azsdkteam@microsoft.com",
|
||||
|
@ -98,6 +98,7 @@
|
|||
"tslint": "tslint ./*.ts ./lib/**/*.ts ./test/**/*.ts ./types/**/*.ts",
|
||||
"test": "npm run tsc && npm run tslint && nyc mocha ./test/**/*.ts -r ts-node/register -t 10000",
|
||||
"start": "node ./dist/lib/autorestPlugin/pluginHost.js",
|
||||
"prepack": "npm install && tsc && npm run tslint"
|
||||
"prepack": "npm install && tsc && npm run tslint",
|
||||
"cli": "node dist/cli.js"
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче