zod#SuperRefinement TypeScript Examples
The following examples show how to use
zod#SuperRefinement.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: config.ts From airnode with MIT License | 6 votes |
validateSecuritySchemesReferences: SuperRefinement<{
ois: OIS[];
apiCredentials: ApiCredentials[];
}> = (config, ctx) => {
config.ois.forEach((ois, index) => {
Object.keys(ois.apiSpecifications.security).forEach((enabledSecuritySchemeName) => {
const enabledSecurityScheme = ois.apiSpecifications.components.securitySchemes[enabledSecuritySchemeName];
if (enabledSecurityScheme && ['apiKey', 'http'].includes(enabledSecurityScheme.type)) {
const securitySchemeApiCredentials = config.apiCredentials.find(
(apiCredentials) => apiCredentials.securitySchemeName === enabledSecuritySchemeName
);
if (!securitySchemeApiCredentials) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `The security scheme is enabled but no credentials are provided in "apiCredentials"`,
path: ['ois', index, 'apiSpecifications', 'security', enabledSecuritySchemeName],
});
}
}
});
});
}
Example #2
Source File: config.ts From airnode with MIT License | 6 votes |
validateTemplateSchemes: SuperRefinement<{
nodeSettings: NodeSettings;
templates: Template[];
}> = (config, ctx) => {
if (config.templates) {
config.templates.forEach((template: any) => {
// Verify that a V0/RRP templates are valid by hashing the airnodeAddress,
// endpointId and encodedParameters
const airnodeAddress = ethers.Wallet.fromMnemonic(config.nodeSettings.airnodeWalletMnemonic).address;
const derivedTemplateId = ethers.utils.solidityKeccak256(
['address', 'bytes32', 'bytes'],
[airnodeAddress, template.endpointId, template.encodedParameters]
);
if (derivedTemplateId !== template.templateId) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Template is invalid`,
path: [template.templateId],
});
}
});
}
}
Example #3
Source File: config.ts From airnode with MIT License | 6 votes |
validateTriggersReferences: SuperRefinement<{
ois: OIS[];
triggers: Triggers;
}> = (config, ctx) => {
forEach(config.triggers, (triggers, triggerSection) => {
forEach(triggers, (trigger, index) => {
const { oisTitle, endpointName } = trigger;
// Check that the OIS with the "oisTitle" from the trigger exists
const ois = config.ois.find((ois) => ois.title === oisTitle);
if (!ois) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `No matching OIS for trigger with OIS title "${oisTitle}"`,
path: ['triggers', triggerSection, index, 'oisTitle'],
});
return;
}
// Check that the OIS contains an endpoint from the trigger
const endpoint = ois.endpoints.find((endpoint) => endpoint.name === endpointName);
if (!endpoint) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `No matching endpoint for trigger with endpoint name "${endpointName}"`,
path: ['triggers', triggerSection, index, 'endpointName'],
});
}
});
});
}
Example #4
Source File: ois.ts From airnode with MIT License | 6 votes |
ensurePathParametersExist: SuperRefinement<Paths> = (paths, ctx) => {
forEach(paths, (pathData, rawPath) => {
forEach(pathData, (paramData, httpMethod) => {
const parameters = paramData!.parameters;
// Match on anything in the path that is braces
// i.e. The path /users/{id}/{action} will match ['{id}', '{action}']
const regex = /\{([^}]+)\}/g;
const matches = rawPath.match(regex)?.map(removeBraces) ?? [];
// Check that all path parameters are defined
matches.forEach((match) => {
const parameter = parameters.find((p) => p.in === 'path' && p.name === match);
if (!parameter) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Path parameter "${match}" is not found in "parameters"`,
path: [rawPath, httpMethod, 'parameters'],
});
}
}, rawPath);
// Check that all parameters are used
parameters.forEach((p, index) => {
if (p.in === 'path' && !matches.includes(p.name)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Parameter "${p.name}" is not found in the URL path`,
path: [rawPath, httpMethod, 'parameters', index],
});
}
});
});
});
}
Example #5
Source File: ois.ts From airnode with MIT License | 5 votes |
ensureSingleParameterUsagePerEndpoint: SuperRefinement<{
endpoints: Endpoint[];
}> = (ois, ctx) => {
ois.endpoints.forEach((endpoint, oisIndex) => {
const params = endpoint.parameters.map((p) => p.operationParameter);
const fixedParams = endpoint.fixedOperationParameters.map((p) => p.operationParameter);
const checkUniqueness = (section: 'parameters' | 'fixedOperationParameters') => {
const paramsToCheck = section === 'parameters' ? params : fixedParams;
paramsToCheck.forEach((param, paramIndex) => {
const count = paramsToCheck.filter((p) => p.in === param.in && p.name === param.name).length;
if (count > 1) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Parameter "${param.name}" in "${param.in}" is used multiple times`,
path: ['ois', 'endpoints', oisIndex, section, paramIndex],
});
}
});
};
// Check uniqueness in the respective sections
checkUniqueness('parameters');
checkUniqueness('fixedOperationParameters');
// Check uniqueness across "parameters" and "fixedOperationParameters"
params.forEach((param, paramIndex) => {
const fixedParam = fixedParams.find((p) => p.in === param.in && p.name === param.name);
if (fixedParam) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Parameter "${param.name}" in "${param.in}" is used in both "parameters" and "fixedOperationParameters"`,
path: ['ois', 'endpoints', oisIndex, 'parameters', paramIndex],
});
// Add also an issue for the fixed parameter. This makes it easier for the user to find the offending parameter
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Parameter "${param.name}" in "${param.in}" is used in both "parameters" and "fixedOperationParameters"`,
path: ['ois', 'endpoints', oisIndex, 'fixedOperationParameters', fixedParams.indexOf(fixedParam)],
});
}
});
});
}
Example #6
Source File: ois.ts From airnode with MIT License | 4 votes |
ensureEndpointAndApiSpecificationParamsMatch: SuperRefinement<{
endpoints: Endpoint[];
apiSpecifications: ApiSpecification;
}> = (ois, ctx) => {
const { apiSpecifications, endpoints } = ois;
// Ensure every "apiSpecification.paths" parameter is defined in "endpoints"
forEach(apiSpecifications.paths, (pathData, rawPath) => {
forEach(pathData, (paramData, httpMethod) => {
const apiEndpoints = endpoints.filter(
({ operation }) => operation.method === httpMethod && operation.path === rawPath
);
if (!apiEndpoints.length) return; // Missing endpoint for apiSpecification should only be a warning
apiEndpoints.forEach((endpoint) => {
paramData!.parameters.forEach((apiParam) => {
const allEndpointParams = [...endpoint.parameters, ...endpoint.fixedOperationParameters];
const endpointParam = allEndpointParams.find(
({ operationParameter }) =>
operationParameter.in === apiParam.in && operationParameter.name === apiParam.name
);
if (!endpointParam) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Parameter "${apiParam.name}" not found in "fixedOperationParameters" or "parameters"`,
path: ['ois', 'endpoints', endpoints.indexOf(endpoint)],
});
}
});
});
});
});
// Ensure every endpoint parameter references parameter from "apiSpecification.paths"
endpoints.forEach((endpoint, endpointIndex) => {
const { operation, parameters, fixedOperationParameters } = endpoint;
const apiSpec = find(apiSpecifications.paths, (pathData, path) => {
if (operation.path !== path) return false;
return !!find(pathData, (_, httpMethod) => operation.method === httpMethod);
});
if (!apiSpec) {
return ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `No matching API specification found in "apiSpecifications" section`,
path: ['ois', 'endpoints', endpointIndex],
});
}
// Ensure every parameter exist in "apiSpecification"
parameters.forEach((endpointParam, endpointParamIndex) => {
const { operationParameter } = endpointParam;
const apiParam = apiSpec[operation.method]!.parameters.find(
(p) => p.in === operationParameter.in && p.name === operationParameter.name
);
if (!apiParam) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `No matching API specification parameter found in "apiSpecifications" section`,
path: ['ois', 'endpoints', endpointIndex, 'parameters', endpointParamIndex],
});
}
});
// Ensure every fixed parameter exist in "apiSpecification"
fixedOperationParameters.forEach((endpointParam, endpointParamIndex) => {
const { operationParameter } = endpointParam;
const apiParam = apiSpec[operation.method]!.parameters.find(
(p) => p.in === operationParameter.in && p.name === operationParameter.name
);
if (!apiParam) {
if (!apiParam) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `No matching API specification parameter found in "apiSpecifications" section`,
path: ['ois', 'endpoints', endpointIndex, 'fixedOperationParameters', endpointParamIndex],
});
}
}
});
});
}