@stoplight/prism-core
Advanced tools
Comparing version 3.1.0 to 3.1.1
@@ -1,3 +0,2 @@ | ||
import { PartialPrismConfig, PrismConfig } from '.'; | ||
import { IPrism, IPrismComponents, PickRequired } from './types'; | ||
export declare function factory<Resource, Input, Output, Config>(defaultConfig: PrismConfig<Config, Input>, defaultComponents: Partial<IPrismComponents<Resource, Input, Output, Config>>): (customConfig?: PartialPrismConfig<Config, Input>, customComponents?: PickRequired<Partial<IPrismComponents<Resource, Input, Output, Config>>, 'logger'>) => IPrism<Resource, Input, Output, Config>; | ||
import { IPrism, IPrismComponents, IPrismConfig } from './types'; | ||
export declare function factory<Resource, Input, Output, Config extends IPrismConfig>(defaultConfig: Config, components: IPrismComponents<Resource, Input, Output, Config>): IPrism<Resource, Input, Output, Config>; |
@@ -8,93 +8,64 @@ "use strict"; | ||
const TaskEither = require("fp-ts/lib/TaskEither"); | ||
const _1 = require("."); | ||
const lodash_1 = require("lodash"); | ||
const security_1 = require("./utils/security"); | ||
function factory(defaultConfig, defaultComponents) { | ||
const prism = (customConfig, customComponents) => { | ||
const components = Object.assign({}, defaultComponents, customComponents); | ||
return { | ||
process: async (input, resources, c) => { | ||
const configMerger = _1.configMergerFactory(defaultConfig, customConfig, c); | ||
const configObj = configMerger(input); | ||
const inputValidations = []; | ||
if (components.router) { | ||
return pipeable_1.pipe(components.router.route({ resources, input, config: configObj }, defaultComponents.router), Either.fold(error => { | ||
if (configObj.mock) { | ||
return TaskEither.left(error); | ||
} | ||
const { message, name, status } = error; | ||
inputValidations.push({ | ||
message, | ||
source: name, | ||
code: status, | ||
severity: types_1.DiagnosticSeverity.Warning, | ||
}); | ||
return TaskEither.right(undefined); | ||
}, value => TaskEither.right(value)), TaskEither.chain(resource => { | ||
if (resource && components.validator && components.validator.validateInput) { | ||
inputValidations.push(...components.validator.validateInput({ | ||
resource, | ||
input, | ||
config: configObj, | ||
}, defaultComponents.validator)); | ||
} | ||
const inputValidationResult = inputValidations.concat(pipeable_1.pipe(security_1.validateSecurity(input, resource), Option_1.fold(() => [], value => [value]))); | ||
if (resource && components.mocker && configObj.mock) { | ||
return pipeable_1.pipe(TaskEither.fromEither(components.mocker.mock({ | ||
resource, | ||
input: { | ||
validations: { | ||
input: inputValidationResult, | ||
}, | ||
data: input, | ||
}, | ||
config: configObj, | ||
}, defaultComponents.mocker)(components.logger.child({ name: 'NEGOTIATOR' }))), TaskEither.map(output => ({ output, resource }))); | ||
} | ||
else if (components.forwarder) { | ||
return pipeable_1.pipe(components.forwarder.fforward({ | ||
resource, | ||
input: { | ||
validations: { | ||
input: inputValidationResult, | ||
}, | ||
data: input, | ||
}, | ||
config: configObj, | ||
}, defaultComponents.forwarder), TaskEither.map(output => ({ output, resource }))); | ||
} | ||
return TaskEither.left(new Error('Nor forwarder nor mocker has been selected. Something is wrong')); | ||
}), TaskEither.map(({ output, resource }) => { | ||
let outputValidations = []; | ||
if (resource && components.validator && components.validator.validateOutput) { | ||
outputValidations = components.validator.validateOutput({ | ||
resource, | ||
output, | ||
config: configObj, | ||
}, defaultComponents.validator); | ||
} | ||
return { | ||
input, | ||
output, | ||
function factory(defaultConfig, components) { | ||
return { | ||
process: async (input, resources, c) => { | ||
const config = lodash_1.defaults(c, defaultConfig); | ||
const inputValidations = []; | ||
return pipeable_1.pipe(components.route({ resources, input, config }), Either.fold(error => { | ||
if (config.mock) { | ||
return TaskEither.left(error); | ||
} | ||
const { message, name, status } = error; | ||
inputValidations.push({ | ||
message, | ||
source: name, | ||
code: status, | ||
severity: types_1.DiagnosticSeverity.Warning, | ||
}); | ||
return TaskEither.right(undefined); | ||
}, value => TaskEither.right(value)), TaskEither.chain(resource => { | ||
if (config.validateRequest && resource && components.validateInput) { | ||
inputValidations.push(...components.validateInput({ | ||
resource, | ||
element: input, | ||
})); | ||
} | ||
const inputValidationResult = inputValidations.concat(pipeable_1.pipe(security_1.validateSecurity(input, resource), Option_1.map(sec => [sec]), Option_1.getOrElse(() => []))); | ||
if (resource && config.mock) { | ||
return pipeable_1.pipe(TaskEither.fromEither(components.mock({ | ||
resource, | ||
input: { | ||
validations: { | ||
input: inputValidations, | ||
output: outputValidations, | ||
input: inputValidationResult, | ||
}, | ||
}; | ||
}))().then(v => pipeable_1.pipe(v, Either.fold(e => { | ||
throw e; | ||
}, o => o))); | ||
data: input, | ||
}, | ||
config, | ||
})(components.logger.child({ name: 'NEGOTIATOR' }))), TaskEither.map(output => ({ output, resource }))); | ||
} | ||
return TaskEither.left(new Error('Resource not defined. This should never happen.')); | ||
}), TaskEither.map(({ output, resource }) => { | ||
let outputValidations = []; | ||
if (config.validateResponse && resource && components.validateOutput) { | ||
outputValidations = components.validateOutput({ | ||
resource, | ||
element: output, | ||
}); | ||
} | ||
return { | ||
input, | ||
output: undefined, | ||
output, | ||
validations: { | ||
input: [], | ||
output: [], | ||
input: inputValidations, | ||
output: outputValidations, | ||
}, | ||
}; | ||
}, | ||
}; | ||
}))().then(v => pipeable_1.pipe(v, Either.fold(e => { | ||
throw e; | ||
}, o => o))); | ||
}, | ||
}; | ||
return prism; | ||
} | ||
exports.factory = factory; |
export * from './types'; | ||
export * from './factory'; | ||
export * from './utils'; | ||
export * from './logger'; |
@@ -6,3 +6,2 @@ "use strict"; | ||
tslib_1.__exportStar(require("./factory"), exports); | ||
tslib_1.__exportStar(require("./utils"), exports); | ||
tslib_1.__exportStar(require("./logger"), exports); |
import { IDiagnostic } from '@stoplight/types'; | ||
import { Either } from 'fp-ts/lib/Either'; | ||
import { Reader } from 'fp-ts/lib/Reader'; | ||
import { TaskEither } from 'fp-ts/lib/TaskEither'; | ||
import { Logger } from 'pino'; | ||
export declare type IPrismDiagnostic = Omit<IDiagnostic, 'range'>; | ||
export interface IPrism<Resource, Input, Output, Config> { | ||
export interface IPrism<Resource, Input, Output, Config extends IPrismConfig> { | ||
process: (input: Input, resources: Resource[], config?: Config) => Promise<IPrismOutput<Input, Output>>; | ||
} | ||
export declare type PartialPrismConfigFactory<C, I> = (input: I, defaultConfig?: PartialPrismConfig<C, I> | PrismConfig<C, I>) => Partial<C>; | ||
export declare type PartialPrismConfig<C, I> = Partial<C> | PrismConfigFactory<C, I> | PartialPrismConfigFactory<C, I>; | ||
export interface IPrismConfig { | ||
mock?: boolean | object; | ||
mock?: object; | ||
security?: boolean | object; | ||
@@ -18,5 +15,7 @@ validateRequest: boolean; | ||
} | ||
export declare type PrismConfigFactory<C, I> = (input: I, defaultConfig?: PrismConfig<C, I>) => C; | ||
export declare type PrismConfig<C, I> = C | PrismConfigFactory<C, I>; | ||
export interface IRouter<Resource, Input, Config> { | ||
export declare type ValidatorFn<Resource, T> = (opts: { | ||
resource: Resource; | ||
element: T; | ||
}) => IPrismDiagnostic[]; | ||
export declare type IPrismComponents<Resource, Input, Output, Config extends IPrismConfig> = { | ||
route: (opts: { | ||
@@ -26,43 +25,12 @@ resources: Resource[]; | ||
config?: Config; | ||
}, defaultRouter?: IRouter<Resource, Input, Config>) => Either<Error, Resource>; | ||
} | ||
export interface IForwarder<Resource, Input, Config, Output> { | ||
forward: (opts: { | ||
resource?: Resource; | ||
}) => Either<Error, Resource>; | ||
validateInput?: ValidatorFn<Resource, Input>; | ||
validateOutput?: ValidatorFn<Resource, Output>; | ||
mock: (opts: { | ||
resource: Resource; | ||
input: IPrismInput<Input>; | ||
config?: Config; | ||
}, defaultForwarder?: IForwarder<Resource, Input, Config, Output>) => Promise<Output>; | ||
fforward: (opts: { | ||
resource?: Resource; | ||
input: IPrismInput<Input>; | ||
config?: Config; | ||
}, defaultForwarder?: IForwarder<Resource, Input, Config, Output>) => TaskEither<Error, Output>; | ||
} | ||
export interface IMocker<Resource, Input, Config, Output> { | ||
mock: (opts: IMockerOpts<Resource, Input, Config>, defaultMocker?: IMocker<Resource, Input, Config, Output>) => Output; | ||
} | ||
export interface IMockerOpts<Resource, Input, Config> { | ||
resource: Resource; | ||
input: IPrismInput<Input>; | ||
config?: Config; | ||
} | ||
export interface IValidator<Resource, Input, Config, Output> { | ||
validateInput?: (opts: { | ||
resource: Resource; | ||
input: Input; | ||
config?: Config; | ||
}, defaultValidator?: IValidator<Resource, Input, Config, Output>) => IPrismDiagnostic[]; | ||
validateOutput?: (opts: { | ||
resource: Resource; | ||
output?: Output; | ||
config?: Config; | ||
}, defaultValidator?: IValidator<Resource, Input, Config, Output>) => IPrismDiagnostic[]; | ||
} | ||
export interface IPrismComponents<Resource, Input, Output, Config> { | ||
router: IRouter<Resource, Input, Config>; | ||
forwarder: IForwarder<Resource, Input, Config, Output>; | ||
mocker: IMocker<Resource, Input, Config, Reader<Logger, Either<Error, Output>>>; | ||
validator: IValidator<Resource, Input, Config, Output>; | ||
}) => Reader<Logger, Either<Error, Output>>; | ||
logger: Logger; | ||
} | ||
}; | ||
export interface IPrismInput<I> { | ||
@@ -75,4 +43,4 @@ data: I; | ||
export interface IPrismOutput<I, O> { | ||
input?: I; | ||
output?: O; | ||
input: I; | ||
output: O; | ||
validations: { | ||
@@ -89,3 +57,2 @@ input: IPrismDiagnostic[]; | ||
}; | ||
export declare type PickRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>; | ||
export declare class ProblemJsonError extends Error { | ||
@@ -92,0 +59,0 @@ readonly name: string; |
@@ -6,4 +6,4 @@ "use strict"; | ||
const forbiddenErr = { | ||
code: 403, | ||
message: 'Invalid credentials used', | ||
code: 401, | ||
message: 'Invalid security scheme used', | ||
severity: types_1.DiagnosticSeverity.Error, | ||
@@ -10,0 +10,0 @@ }; |
@@ -11,6 +11,3 @@ "use strict"; | ||
function gatherInvalidResults(error, invalidSecuritySchemes) { | ||
const firstLeftValue = pipeable_1.pipe(error, Either_1.fold(lodash_1.identity, lodash_1.identity)); | ||
const invalidSecurity = firstLeftValue.code !== 401 | ||
? firstLeftValue | ||
: gatherWWWAuthHeader(invalidSecuritySchemes, ['tags'], firstLeftValue); | ||
const invalidSecurity = gatherWWWAuthHeader(invalidSecuritySchemes, ['tags'], error.left); | ||
return Option_1.some(invalidSecurity); | ||
@@ -17,0 +14,0 @@ } |
{ | ||
"name": "@stoplight/prism-core", | ||
"version": "3.1.0", | ||
"version": "3.1.1", | ||
"main": "dist/index.js", | ||
@@ -26,3 +26,3 @@ "types": "dist/index.d.ts", | ||
}, | ||
"gitHead": "9628bb61932edca228c007ec1be477fcd3123ab7" | ||
"gitHead": "302794128dcadf28193c3cb90f1560dc1f7c4dcc" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33983
27
498