mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
436 lines
13 KiB
JavaScript
436 lines
13 KiB
JavaScript
const Yup = require('yup');
|
|
const { uidSchema } = require('../common');
|
|
|
|
const environmentVariablesSchema = Yup.object({
|
|
uid: uidSchema,
|
|
name: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
type: Yup.string().oneOf(['text']).required('type is required'),
|
|
enabled: Yup.boolean().defined(),
|
|
secret: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const environmentSchema = Yup.object({
|
|
uid: uidSchema,
|
|
name: Yup.string().min(1).required('name is required'),
|
|
variables: Yup.array().of(environmentVariablesSchema).required('variables are required')
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const environmentsSchema = Yup.array().of(environmentSchema);
|
|
|
|
const keyValueSchema = Yup.object({
|
|
uid: uidSchema,
|
|
name: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
description: Yup.string().nullable(),
|
|
enabled: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const varsSchema = Yup.object({
|
|
uid: uidSchema,
|
|
name: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
description: Yup.string().nullable(),
|
|
enabled: Yup.boolean(),
|
|
|
|
// todo
|
|
// anoop(4 feb 2023) - nobody uses this, and it needs to be removed
|
|
local: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const requestUrlSchema = Yup.string().min(0).defined();
|
|
const requestMethodSchema = Yup.string()
|
|
.oneOf(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'TRACE'])
|
|
.required('method is required');
|
|
|
|
const graphqlBodySchema = Yup.object({
|
|
query: Yup.string().nullable(),
|
|
variables: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const multipartFormSchema = Yup.object({
|
|
uid: uidSchema,
|
|
type: Yup.string().oneOf(['file', 'text']).required('type is required'),
|
|
name: Yup.string().nullable(),
|
|
value: Yup.mixed().when('type', {
|
|
is: 'file',
|
|
then: Yup.array().of(Yup.string().nullable()).nullable(),
|
|
otherwise: Yup.string().nullable()
|
|
}),
|
|
description: Yup.string().nullable(),
|
|
contentType: Yup.string().nullable(),
|
|
enabled: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
|
|
const fileSchema = Yup.object({
|
|
uid: uidSchema,
|
|
filePath: Yup.string().nullable(),
|
|
contentType: Yup.string().nullable(),
|
|
selected: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const requestBodySchema = Yup.object({
|
|
mode: Yup.string()
|
|
.oneOf(['none', 'json', 'text', 'xml', 'formUrlEncoded', 'multipartForm', 'graphql', 'sparql', 'file'])
|
|
.required('mode is required'),
|
|
json: Yup.string().nullable(),
|
|
text: Yup.string().nullable(),
|
|
xml: Yup.string().nullable(),
|
|
sparql: Yup.string().nullable(),
|
|
formUrlEncoded: Yup.array().of(keyValueSchema).nullable(),
|
|
multipartForm: Yup.array().of(multipartFormSchema).nullable(),
|
|
graphql: graphqlBodySchema.nullable(),
|
|
file: Yup.array().of(fileSchema).nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authAwsV4Schema = Yup.object({
|
|
accessKeyId: Yup.string().nullable(),
|
|
secretAccessKey: Yup.string().nullable(),
|
|
sessionToken: Yup.string().nullable(),
|
|
service: Yup.string().nullable(),
|
|
region: Yup.string().nullable(),
|
|
profileName: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authBasicSchema = Yup.object({
|
|
username: Yup.string().nullable(),
|
|
password: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authWsseSchema = Yup.object({
|
|
username: Yup.string().nullable(),
|
|
password: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authBearerSchema = Yup.object({
|
|
token: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authDigestSchema = Yup.object({
|
|
username: Yup.string().nullable(),
|
|
password: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
|
|
|
|
const authNTLMSchema = Yup.object({
|
|
username: Yup.string().nullable(),
|
|
password: Yup.string().nullable(),
|
|
domain: Yup.string().nullable()
|
|
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authApiKeySchema = Yup.object({
|
|
key: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
placement: Yup.string().oneOf(['header', 'queryparams']).nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const oauth2AuthorizationAdditionalParametersSchema = Yup.object({
|
|
name: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
sendIn: Yup.string()
|
|
.oneOf(['headers', 'queryparams'])
|
|
.required('send in property is required'),
|
|
enabled: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const oauth2AdditionalParametersSchema = Yup.object({
|
|
name: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
sendIn: Yup.string()
|
|
.oneOf(['headers', 'queryparams', 'body'])
|
|
.required('send in property is required'),
|
|
enabled: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const oauth2Schema = Yup.object({
|
|
grantType: Yup.string()
|
|
.oneOf(['client_credentials', 'password', 'authorization_code'])
|
|
.required('grantType is required'),
|
|
username: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
password: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
callbackUrl: Yup.string().when('grantType', {
|
|
is: (val) => ['authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
authorizationUrl: Yup.string().when('grantType', {
|
|
is: (val) => ['authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
accessTokenUrl: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
clientId: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
clientSecret: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
scope: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
state: Yup.string().when('grantType', {
|
|
is: (val) => ['authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
pkce: Yup.boolean().when('grantType', {
|
|
is: (val) => ['authorization_code'].includes(val),
|
|
then: Yup.boolean().default(false),
|
|
otherwise: Yup.boolean()
|
|
}),
|
|
credentialsPlacement: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
credentialsId: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
tokenPlacement: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
tokenHeaderPrefix: Yup.string().when(['grantType', 'tokenPlacement'], {
|
|
is: (grantType, tokenPlacement) =>
|
|
['client_credentials', 'password', 'authorization_code'].includes(grantType) && tokenPlacement === 'header',
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
tokenQueryKey: Yup.string().when(['grantType', 'tokenPlacement'], {
|
|
is: (grantType, tokenPlacement) =>
|
|
['client_credentials', 'password', 'authorization_code'].includes(grantType) && tokenPlacement === 'url',
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
refreshTokenUrl: Yup.string().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.string().nullable(),
|
|
otherwise: Yup.string().nullable().strip()
|
|
}),
|
|
autoRefreshToken: Yup.boolean().when('grantType', {
|
|
is: (val) => ['client_credentials', 'password', 'authorization_code'].includes(val),
|
|
then: Yup.boolean().default(false),
|
|
otherwise: Yup.boolean()
|
|
}),
|
|
autoFetchToken: Yup.boolean().when('grantType', {
|
|
is: (val) => ['authorization_code'].includes(val),
|
|
then: Yup.boolean().default(true),
|
|
otherwise: Yup.boolean()
|
|
}),
|
|
additionalParameters: Yup.object({
|
|
authorization: Yup.array().of(oauth2AuthorizationAdditionalParametersSchema).optional(),
|
|
token: Yup.array().of(oauth2AdditionalParametersSchema).optional(),
|
|
refresh: Yup.array().of(oauth2AdditionalParametersSchema).optional()
|
|
})
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const authSchema = Yup.object({
|
|
mode: Yup.string()
|
|
.oneOf(['inherit', 'none', 'awsv4', 'basic', 'bearer', 'digest', 'ntlm', 'oauth2', 'wsse', 'apikey'])
|
|
.required('mode is required'),
|
|
awsv4: authAwsV4Schema.nullable(),
|
|
basic: authBasicSchema.nullable(),
|
|
bearer: authBearerSchema.nullable(),
|
|
ntlm: authNTLMSchema.nullable(),
|
|
digest: authDigestSchema.nullable(),
|
|
oauth2: oauth2Schema.nullable(),
|
|
wsse: authWsseSchema.nullable(),
|
|
apikey: authApiKeySchema.nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict()
|
|
.nullable();
|
|
|
|
const requestParamsSchema = Yup.object({
|
|
uid: uidSchema,
|
|
name: Yup.string().nullable(),
|
|
value: Yup.string().nullable(),
|
|
description: Yup.string().nullable(),
|
|
type: Yup.string().oneOf(['query', 'path']).required('type is required'),
|
|
enabled: Yup.boolean()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
// Right now, the request schema is very tightly coupled with http request
|
|
// As we introduce more request types in the future, we will improve the definition to support
|
|
// schema structure based on other request type
|
|
const requestSchema = Yup.object({
|
|
url: requestUrlSchema,
|
|
method: requestMethodSchema,
|
|
headers: Yup.array().of(keyValueSchema).required('headers are required'),
|
|
params: Yup.array().of(requestParamsSchema).required('params are required'),
|
|
auth: authSchema,
|
|
body: requestBodySchema,
|
|
script: Yup.object({
|
|
req: Yup.string().nullable(),
|
|
res: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict(),
|
|
vars: Yup.object({
|
|
req: Yup.array().of(varsSchema).nullable(),
|
|
res: Yup.array().of(varsSchema).nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict()
|
|
.nullable(),
|
|
assertions: Yup.array().of(keyValueSchema).nullable(),
|
|
tests: Yup.string().nullable(),
|
|
docs: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const folderRootSchema = Yup.object({
|
|
request: Yup.object({
|
|
headers: Yup.array().of(keyValueSchema).nullable(),
|
|
auth: authSchema,
|
|
script: Yup.object({
|
|
req: Yup.string().nullable(),
|
|
res: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict()
|
|
.nullable(),
|
|
vars: Yup.object({
|
|
req: Yup.array().of(varsSchema).nullable(),
|
|
res: Yup.array().of(varsSchema).nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict()
|
|
.nullable(),
|
|
tests: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict()
|
|
.nullable(),
|
|
docs: Yup.string().nullable(),
|
|
meta: Yup.object({
|
|
name: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict()
|
|
.nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.nullable();
|
|
|
|
const itemSchema = Yup.object({
|
|
uid: uidSchema,
|
|
type: Yup.string().oneOf(['http-request', 'graphql-request', 'folder', 'js']).required('type is required'),
|
|
seq: Yup.number().min(1),
|
|
name: Yup.string().min(1, 'name must be at least 1 character').required('name is required'),
|
|
request: requestSchema.when('type', {
|
|
is: (type) => ['http-request', 'graphql-request'].includes(type),
|
|
then: (schema) => schema.required('request is required when item-type is request')
|
|
}),
|
|
fileContent: Yup.string().when('type', {
|
|
// If the type is 'js', the fileContent field is expected to be a string.
|
|
// This can include an empty string, indicating that the JS file may not have any content.
|
|
is: 'js',
|
|
then: Yup.string(),
|
|
// For all other types, the fileContent field is not required and can be null.
|
|
otherwise: Yup.string().nullable()
|
|
}),
|
|
root: Yup.mixed().when('type', {
|
|
is: 'folder',
|
|
then: folderRootSchema,
|
|
otherwise: Yup.mixed().nullable().notRequired()
|
|
}),
|
|
items: Yup.lazy(() => Yup.array().of(itemSchema)),
|
|
filename: Yup.string().nullable(),
|
|
pathname: Yup.string().nullable()
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
const collectionSchema = Yup.object({
|
|
version: Yup.string().oneOf(['1']).required('version is required'),
|
|
uid: uidSchema,
|
|
name: Yup.string().min(1, 'name must be at least 1 character').required('name is required'),
|
|
items: Yup.array().of(itemSchema),
|
|
activeEnvironmentUid: Yup.string()
|
|
.length(21, 'activeEnvironmentUid must be 21 characters in length')
|
|
.matches(/^[a-zA-Z0-9]*$/, 'uid must be alphanumeric')
|
|
.nullable(),
|
|
environments: environmentsSchema,
|
|
pathname: Yup.string().nullable(),
|
|
runnerResult: Yup.object({
|
|
items: Yup.array()
|
|
}),
|
|
runtimeVariables: Yup.object(),
|
|
brunoConfig: Yup.object(),
|
|
root: folderRootSchema
|
|
})
|
|
.noUnknown(true)
|
|
.strict();
|
|
|
|
module.exports = {
|
|
requestSchema,
|
|
itemSchema,
|
|
environmentSchema,
|
|
environmentsSchema,
|
|
collectionSchema
|
|
};
|