Configuration directive system for custom transformations, suppressions, and rules processing with support for conditional execution.
interface Directive {
from?: string[] | string;
where?: string[] | string;
reason?: string[];
suppress?: string[] | string;
set?: string[] | string;
transform?: string[] | string;
"text-transform"?: string[] | string;
test?: string[] | string;
debug?: boolean;
}Configuration directive interface for specifying transformations and rules to apply to specifications.
Properties:
from?: string[] | string - Source specification or document to operate onwhere?: string[] | string - JSONPath or selector for target locationreason?: string[] - Reasons or comments explaining the directivesuppress?: string[] | string - Validation rules or warnings to suppressset?: string[] | string - Values to set at target locationtransform?: string[] | string - JavaScript transformation expressions"text-transform"?: string[] | string - Text transformation expressionstest?: string[] | string - Test conditions for applying the directivedebug?: boolean - Enable debug output for this directiveclass ResolvedDirective {
constructor(directive: Directive);
from: string[];
where: string[];
reason?: string[];
suppress: string[];
transform: string[];
test: string[];
debug: boolean;
get name(): string;
}Processed and normalized directive with array-normalized properties.
Constructor:
constructor(directive: Directive) - Creates resolved directive from raw directiveProperties:
from: string[] - Normalized source specificationswhere: string[] - Normalized target selectorsreason?: string[] - Optional reasons for the directivesuppress: string[] - Normalized suppression rulestransform: string[] - Normalized transformation expressions (includes text-transform)test: string[] - Normalized test conditionsdebug: boolean - Debug flag for detailed outputMethods:
get name(): string - Returns a descriptive name combining from and where propertiesfunction resolveDirectives(
config: AutorestConfiguration,
predicate?: (each: ResolvedDirective) => boolean
): ResolvedDirective[];Resolves and expands all directives from configuration, including macro expansion and conditional filtering.
Parameters:
config: AutorestConfiguration - Configuration containing directives and macro declarationspredicate?: (each: ResolvedDirective) => boolean - Optional filter condition for directivesReturns:
ResolvedDirective[] - Array of resolved and expanded directive objectsExample:
import { resolveDirectives } from "@autorest/configuration";
// Resolve all directives
const allDirectives = resolveDirectives(config);
// Resolve only transform directives
const transformDirectives = resolveDirectives(config,
directive => directive.transform.length > 0
);
// Resolve only suppression directives
const suppressDirectives = resolveDirectives(config,
directive => directive.suppress.length > 0
);Methods:
get name(): string - Returns descriptive name combining from and where propertiesSuppress validation warnings or errors for specific scenarios:
const suppressDirective: Directive = {
from: "swagger-document",
where: "$.paths.*.*.responses",
suppress: ["R3016"], // Suppress specific validation rule
reason: ["Legacy API maintains this pattern for backward compatibility"]
};Apply JavaScript transformations to modify specifications:
const transformDirective: Directive = {
from: "swagger-document",
where: "$.paths.*.*",
transform: [
"return $.operationId = $.operationId || `${$.method}_${$.path.replace(/[^a-zA-Z0-9]/g, '_')}`"
],
reason: ["Generate operation IDs for operations missing them"]
};Apply text-based transformations:
const textTransformDirective: Directive = {
from: "code-model-v4",
where: "$.operationGroups[*].operations[*].language.default.name",
"text-transform": [
"return $.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()"
]
};Set specific values at target locations:
const setDirective: Directive = {
from: "swagger-document",
where: "$.info.version",
set: ["1.0.0"],
reason: ["Override version for consistency"]
};Apply test conditions for directive execution:
const conditionalDirective: Directive = {
from: "swagger-document",
where: "$.paths.*.*",
test: ["$.operationId === undefined"],
transform: ["return $.operationId = 'GeneratedOperation'"],
reason: ["Add operation ID only if missing"]
};function processDirectives(
directives: Directive[],
context: any
): ResolvedDirective[];Processes an array of directives and returns resolved directives for execution.
Parameters:
directives: Directive[] - Array of raw directives to processcontext: any - Context object for directive evaluationReturns:
ResolvedDirective[] - Array of processed and normalized directivesimport { Directive, ResolvedDirective } from "@autorest/configuration";
const directives: Directive[] = [
{
from: "swagger-document",
where: "$.info.title",
set: "My API v2",
reason: ["Update API title for new version"]
},
{
suppress: ["R2029"],
reason: ["Suppress parameter description requirement"]
}
];
// Process directives
const resolvedDirectives = directives.map(d => new ResolvedDirective(d));
// Access resolved properties
resolvedDirectives.forEach(directive => {
console.log(`Directive: ${directive.name}`);
console.log(`Suppresses: ${directive.suppress}`);
console.log(`Transforms: ${directive.transform}`);
});const complexDirective: Directive = {
from: "swagger-document",
where: "$.paths.*.*",
transform: [
`
// Add standard error responses if missing
if (!$.responses['400']) {
$.responses['400'] = {
description: "Bad Request",
schema: { $ref: "#/definitions/Error" }
};
}
if (!$.responses['500']) {
$.responses['500'] = {
description: "Internal Server Error",
schema: { $ref: "#/definitions/Error" }
};
}
return $;
`
],
reason: ["Ensure all operations have standard error responses"]
};const conditionalDirectives: Directive[] = [
{
from: "swagger-document",
where: "$.paths.*.*",
test: ["$.deprecated === true"],
transform: ["$.summary = '[DEPRECATED] ' + ($.summary || '')"],
reason: ["Mark deprecated operations in summary"]
},
{
from: "swagger-document",
where: "$.definitions.*",
test: ["$.required && $.required.length === 0"],
transform: ["delete $.required; return $"],
reason: ["Remove empty required arrays"]
}
];Directives are executed within a controlled context that provides:
Directives can operate across multiple specification documents:
const crossDocDirective: Directive = {
from: ["swagger-document", "openapi-document"],
where: "$.info",
transform: [
"$.contact = { email: 'api-support@company.com' }; return $"
]
};Enable detailed debugging information:
const debugDirective: Directive = {
from: "swagger-document",
where: "$.paths.*.*",
transform: ["console.log('Processing:', $.operationId); return $"],
debug: true
};Directives are processed in order and can build upon each other:
const chainedDirectives: Directive[] = [
// First, normalize operation IDs
{
from: "swagger-document",
where: "$.paths.*.*",
transform: ["return $.operationId = $.operationId || 'operation'"]
},
// Then, ensure they're unique
{
from: "swagger-document",
where: "$.paths.*.*",
transform: [
"const existing = globalThis.operationIds = globalThis.operationIds || new Set();" +
"let id = $.operationId; let counter = 1;" +
"while (existing.has(id)) { id = $.operationId + counter++; }" +
"existing.add(id); return $.operationId = id;"
]
}
];