@spartaficial/openapi-core reference
@spartaficial/openapi-core is the library the four generators are built on: it loads a specification, resolves references across files, walks and filters operations, derives names, serialises parameters and provides the configuration and command-line plumbing a generator needs. This page is for developers who want to build their own generator, or a one-off script, on the same foundation. It lists every export by group with a one-line purpose; the sections before the tables show how the pieces fit together.
Installation
npm install --save-dev @spartaficial/openapi-core
The package ships CommonJS and ES module builds with type declarations for both, so import and require both work. It has no peer dependencies.
Walking a spec's operations
Most generators do the same three things: load the spec, visit every operation that survives the configured filters, and name what they find. The core does each of them for you.
import {
createFilterStatistics,
forEachOperation,
formatFilterStatistics,
getOperationName,
loadOpenAPISpec,
} from "@spartaficial/openapi-core";
const warn = (message: string) => console.warn(message);
const spec = loadOpenAPISpec("openapi.yaml", {
warn,
refMappings: { "https://schemas.acme.com/v2/": "./specs/acme/" },
});
const stats = createFilterStatistics();
forEachOperation(
spec,
{
operationFilters: { includeTags: ["users"], excludeDeprecated: true },
stripPathPrefix: "/api/v1",
filterPath: "original",
stats,
warn,
},
({ path, originalPath, method, operation }) => {
const name = getOperationName(operation.operationId, method, path);
console.log(`${method.toUpperCase()} ${originalPath} -> ${name}`);
}
);
console.log(formatFilterStatistics(stats));
loadOpenAPISpec throws a FileOperationError when the file is missing and a SpecValidationError when it is not an OpenAPI document, is empty, or references a remote document that refMappings does not cover. Everything the loader noticed but did not stop for, such as a target renamed to avoid a clash with one of your schemas, goes to warn. How references across files are resolved is explained in Specs and references.
forEachOperation yields one OperationVisit per operation: the path with any prefix stripped, the originalPath, the lowercase method, the operation object and the pathItem it came from (for path-level parameters). The filter semantics are those of every generator and are described in Operation filters. forEachOperation verifies the licence the first time it runs in a process; see Licensing.
When you want the operation already digested into parameters, body and response, use extractEndpoints, which runs on top of forEachOperation:
import { extractEndpoints } from "@spartaficial/openapi-core";
const endpoints = extractEndpoints(spec, {
useOperationId: true,
preferredContentTypes: ["application/json"],
trackStatusCode: true,
warn,
});
for (const endpoint of endpoints) {
}
Each EndpointInfo carries the declared style, explode and allowReserved of its parameters, so a client generator can hand them to the serialisation helpers in the table below.
Building a command-line generator
The same module also provides the shape every generator's CLI has: a configuration file validated by a Zod schema, a defaults block merged into each spec, and a batch run that exits non-zero when any spec fails.
import {
BaseDefaultsSchema,
BaseGeneratorOptionsSchema,
createConfigLoader,
ExecutionModeSchema,
handleCliError,
mergeAllSpecsWithDefaults,
runConfigMode,
} from "@spartaficial/openapi-core";
import { z } from "zod";
const SpecSchema = BaseGeneratorOptionsSchema.extend({
outputTypes: z.string(),
outputDocs: z.string(),
});
const ConfigSchema = z.strictObject({
defaults: BaseDefaultsSchema.optional(),
specs: z.array(SpecSchema).min(1),
executionMode: ExecutionModeSchema.optional(),
});
type ConfigFile = z.infer<typeof ConfigSchema>;
const { loadConfig, getResolvedConfigPath } = createConfigLoader<ConfigFile>(
{ packageName: "openapi-to-docs" },
ConfigSchema
);
try {
await runConfigMode({
loadConfig,
getResolvedConfigPath,
productName: "openapi-to-docs",
mergeConfigWithDefaults: config => mergeAllSpecsWithDefaults(config),
createGenerator: spec => new DocsGenerator(spec),
});
} catch (error) {
handleCliError(error, { showStackTrace: true });
}
BaseGeneratorOptionsSchema already declares the options every generator shares (input, outputTypes, operationFilters, stripSchemaPrefix, stripPathPrefix, useOperationId, prefix, suffix, refMappings, showStats, showWarnings, fileHeader, batchSize and the rest); extending it is what keeps the option names the same across generators. runConfigMode loads the config, calls prepareGeneration, merges the defaults, runs the batch and exits with its code, which is exactly what the four published CLIs do; see Command-line reference.
Spec parsing
| Export | Purpose |
|---|
loadOpenAPISpec(inputPath, options?) | Read a YAML or JSON file, validate that it is an OpenAPI document and inline every $ref to another document. |
loadOpenAPISpecCached(inputPath, cache, options?) | The same, through an LRUCache keyed on the path and the refMappings, for generators that read one spec several times. |
bundleExternalRefs(spec, baseDir, options?) | Inline the external $refs of an already parsed document into its own components, rewriting the references. |
applyRefMappings(documentPath, mappings) | Map a remote document URL to a local path by longest matching prefix, or undefined when no mapping covers it. |
ParseOpenAPISpecOptions | validate, warn and refMappings for the loaders. |
BundleExternalRefsOptions | warn, refMappings and maxDocuments for the bundler. |
Reference resolution
| Export | Purpose |
|---|
resolveRefName(ref) | The last segment of a $ref, so #/components/schemas/User gives User. |
resolveRequestBodyRef(requestBody, spec) | Follow a $ref to components.requestBodies, or return the inline body unchanged. |
resolveResponseRef(response, spec) | Follow a $ref to components.responses, or return the inline response unchanged. |
mergeParameters(pathParams, operationParams, spec, warn?) | Combine path-level and operation-level parameters, resolving $refs, with the operation's entry winning. |
Operation iteration and filtering
| Export | Purpose |
|---|
forEachOperation(spec, options, visit) | Visit every operation that passes the filters, with prefix stripping applied. Verifies the licence on first use; see Licensing. |
extractEndpoints(spec, options?) | Turn every surviving operation into an EndpointInfo: method name, parameters by location, request body, success response. |
getEndpointStats(spec, options?) | Count paths, operations and operations that survive the filters. |
shouldIncludeOperation(operation, path, method, filters?, stats?) | Apply include and exclude filters to one operation; exclusions always win. |
validateFilters(stats, filters, warn, options?) | Warn about filter patterns that matched nothing. |
createFilterStatistics(extraCounters?) | A zeroed FilterStatistics object, optionally with generator-specific counters. |
formatFilterStatistics(stats, options?) | Render the statistics as the text the generators embed in their output. |
OperationVisit, ForEachOperationOptions | What forEachOperation yields and accepts. |
EndpointInfo, ParameterInfo, RequestBodyInfo, EndpointStats, ExtractEndpointsOptions | The shapes extractEndpoints and getEndpointStats produce and accept. |
FilterStatistics, FilterBreakdownEntry, FilterReportOptions | Statistics tracking for the filters. |
OperationFilters | The filter options shared by every generator. |
Name utilities
| Export | Purpose |
|---|
toPascalCase(value) | PascalCase, sanitised to a valid TypeScript identifier. |
toCamelCase(value, options?) | camelCase, with optional prefix and suffix. |
capitalize(value) | Capitalise across dashes, underscores and dots. |
applyFormatting(name, prefix?, suffix?) | Apply a prefix and suffix to a PascalCase name. |
getOperationName(operationId, method, path, useOperationId?) | PascalCase operation name from the operationId, or from method and path. |
normalizeSchemaTypeName(name) | The type name every generator derives for a schema, so generated files agree with each other. |
deriveClassName(outputPath) | A class name from an output file path. |
generateQueryParamsTypeName, generateHeaderParamsTypeName | Names for the per-operation parameter types. |
generateInlineRequestTypeName, generateInlineResponseTypeName | Names for inline request and response types. |
contentTypeSuffix(contentType), statusCodeSuffix(statusCode) | The suffixes that distinguish variants of one operation by content type or status code. |
createNameRegistry(), formatNameCollision(name, source, previous) | Record emitted identifiers and word the collision warning the way every generator does. |
NamingOptions, NameRegistry | Option and registry types. |
The naming rules themselves are described for users in Naming.
Method naming
| Export | Purpose |
|---|
pathToPascalCase(path) | /users/{userId} becomes UsersByUserId. |
generateHttpMethodName(method, path) | getUsersByUserId from get and /users/{userId}. |
extractPathParams(path) | The placeholder names in a path template. |
sanitizeOperationId(operationId) | A valid camelCase identifier from an operationId. |
sanitizeParamName(name) | A valid parameter identifier from a path parameter name. |
Schema traversal
| Export | Purpose |
|---|
extractSchemaRefs(schema, refs) | Add every schema name a schema refers to into the refs set. |
expandTransitiveReferences(names, spec) | Grow a set of schema names in place until it covers everything they reference. |
detectCircularReferences(spec) | The names of the schemas that lie on a reference cycle. |
topologicalSortSchemas(dependencies, circularSchemas?) | Order schema names so that each is declared after what it depends on, given a dependency graph. |
analyzeSchemaUsage(spec) | Whether each schema is used in requests, responses or both, for readOnly/writeOnly handling. |
classifyEnumType(values) | Whether an enum is all strings, all numbers, all booleans or mixed. |
collectDiscriminatedUnionMembers(spec) | Every schema that is a member of a discriminated union. |
SchemaContext, SchemaUsageAnalysis | The usage classification types. |
| Export | Purpose |
|---|
shouldIgnoreHeader(name, patterns?) | Case-insensitive match of a header name against ignoreHeaders patterns. |
filterHeaders(headers, patterns?) | Drop the header parameters that match. |
validateIgnorePatterns(patterns, spec, warn?) | Warn about patterns that match no header declared anywhere in the specification. |
Pattern utilities
| Export | Purpose |
|---|
stripPrefix(name, prefix?) | Strip a literal or glob prefix from a schema name (stripSchemaPrefix). |
stripPathPrefix(path, prefix?) | Strip a literal or glob prefix from a path at a segment boundary, keeping the leading /. |
String utilities
| Export | Purpose |
|---|
escapeJSDoc(text) | Make text safe inside a JSDoc comment (*/ cannot close it early). |
escapeDescription(text) | Make text safe inside a .describe() string. |
escapePattern(pattern) | Make a pattern safe inside a regular expression literal. |
quoteStringLiteral(value) | Quote a spec string as a JavaScript string literal. |
needsQuoting(name) | Whether a property name must be quoted in generated TypeScript. |
quotePropertyName(name), formatPropertyName(name), generatePropertyAccess(object, name) | Property names and accesses that are valid whatever the name contains. |
isNullable(schema) | nullable: true (3.0) or a type array containing "null" (3.1). |
getPrimaryType(schema) | The non-null type of a schema whose type is an array. |
hasMultipleTypes(schema) | Whether a type array has more than one non-null member. |
Content types
| Export | Purpose |
|---|
selectContentType(available, preferred?) | The first preferred content type a response or body offers, honouring wildcards, else the first available. |
getResponseParseMethod(contentType, fallback?) | Whether a body should be read as json, text or raw body, and whether the type was unknown. |
normalizeContentType(contentType) | Lowercase, without parameters such as charset. |
DEFAULT_PREFERRED_CONTENT_TYPES | ["application/json"]. |
ContentTypeParseResult, FallbackContentTypeParsing | The result type and the "json" | "text" | "body" fallback. |
Parameter serialisation
These implement the style and explode rules of the OpenAPI specification; the generated Playwright and k6 clients ship their own copies so that generated code never imports this package.
| Export | Purpose |
|---|
resolveParameterSerialization(style?, explode?, allowReserved?) | Fill in the OpenAPI defaults (form, explode: true) for a query parameter. |
isNonDefaultSerialization(serialization) | Whether a client needs to carry this parameter's serialisation explicitly. |
serializeQueryParam(name, value, serialization?) | The name/value pairs one query parameter contributes. |
serializeQueryParams(params, serializations?) | The pairs for a whole parameter object. |
buildQueryStringFromParams(params, serializations?) | An encoded query string including the leading ?, or "". |
encodeQueryValue(value, allowReserved?) | Percent-encode a value, leaving RFC 3986 reserved characters alone when asked. |
resolvePathParameterSerialization(style?, explode?) | Fill in the defaults (simple, explode: false) for a path parameter. |
isNonDefaultPathSerialization(serialization) | Whether a path parameter's serialisation has to be emitted. |
serializePathParam(name, value, serialization?) | The text that replaces a {placeholder} for simple, label and matrix styles. |
DEFAULT_QUERY_SERIALIZATION, DEFAULT_PATH_SERIALIZATION | The OpenAPI defaults as constants. |
QueryParameterStyle, PathParameterStyle, ParameterSerialization, PathParameterSerialization, ParameterSerializationMap, PathParameterSerializationMap, QueryPair | The types. |
Configuration loading, schemas and merging
| Export | Purpose |
|---|
createConfigLoader(options, schema) | A loadConfig(path?) that discovers <name>.config.{ts,json} or a package.json key and validates it, plus getResolvedConfigPath(). |
mergeCliWithConfig(specConfig, cliOptions) | Overlay command-line options on a spec; undefined options do not override. |
BaseGeneratorOptionsSchema, BaseDefaultsSchema | The shared spec and defaults schemas to extend. |
OperationFiltersSchema, RequestResponseOptionsSchema, ExecutionModeSchema, RegexPatternSchema | Reusable schema parts. |
refineOutputPaths(spec, ctx) | A superRefine that enforces the rules around outputTypes, outputZodSchemas and the deprecated output. |
mergeSpecWithDefaults(defaults, spec, options?) | Merge a defaults block into one spec; the spec's own values win. |
mergeAllSpecsWithDefaults(config) | The same for every spec in a config. |
mergeAllSpecsWithDeprecatedOutput(config, packageName) | The same, additionally resolving the deprecated output alias to outputTypes. |
createDeprecatedOutputResolver(packageName), omitUndefined(value) | Building blocks of the merge helpers. |
formatConfigValidationError(error, filepath, configPath, options?) | Turn a Zod validation error into the message the CLIs print, with per-field hints. |
createTypeScriptLoader() | The loader that transpiles a .ts config file and reports a missing import as a MissingDependencyError. |
ConfigLoader, ConfigLoaderOptions, BaseGeneratorOptionsInput, BaseDefaultsInput, BaseOperationFilters, RequestResponseOptions, MergeableConfig, MergeSpecWithDefaultsOptions, CustomFieldMessages, FormatZodErrorsOptions | The types. |
CLI utilities
| Export | Purpose |
|---|
runConfigMode(options) | Load the config, call prepareGeneration, merge defaults, run the batch and exit with its code. |
runInitCommand(options) | The interactive init scaffold: overwrite confirmation, spec file prompt, your questions, config written, next steps. |
promptForSpecFile(options?) | The spec file prompt on its own, listing files under spec/ and specs/. |
handleCliError(error, options?) | Print an error the way the CLIs do (bare for configuration errors, Error: otherwise) and exit with code 1. |
readPackageVersion(cliDirname) | The version from the package.json next to a CLI's build output, for --version. |
getStringField(value, field), getBooleanField(value, field) | Read a typed field off an untrusted object, such as prompt answers. |
getRandomCeriosMessage() | The greeting the CLIs print. |
RunConfigModeOptions, RunInitCommandOptions, InitConfigResult, PromptForSpecFileOptions, RunnableConfig | The option types. |
Classes
| Export | Purpose |
|---|
LRUCache<K, V> | A least-recently-used cache; new LRUCache(maxSize), with get, set, has, clear. |
WarningCollector | Collects warnings during a spec and prints them as one block; disabled when showWarnings is false. |
GeneratorError | Base class of every error below, with a code and optional context. |
SpecValidationError | The specification is not valid OpenAPI, is empty, or has an unresolvable reference. |
FileOperationError | A file could not be read or written; carries filePath. |
ConfigValidationError | The configuration file is missing or failed validation; carries configPath. |
ConfigurationError | Options passed programmatically are missing something required. |
CliOptionsError | Command-line flags are inconsistent, such as an incomplete direct mode. |
SchemaGenerationError, CircularReferenceError | A schema could not be generated; the latter carries the referencePath of the cycle. |
MissingDependencyError | A module a .ts config imports is not installed; carries packageName. |
WarningContext | Constructor options of WarningCollector. |
Batch execution
| Export | Purpose |
|---|
executeBatch(specs, executionMode, createGenerator, batchSize) | Run every spec, in parallel batches or sequentially, collecting failures instead of throwing, and print the summary. |
getBatchExitCode(summary) | 1 when any spec failed, otherwise 0. |
Generator | What createGenerator must return: an object with generate(): void. |
BatchExecutionSummary, SpecResult | The summary and per-spec result types. |
Run preparation
| Export | Purpose |
|---|
prepareGeneration(productName, resolvedConfigPath?) | Verify the licence for a run and return the one-line summary the CLIs print; exits the process when verification fails. See Licensing. |
runConfigMode calls it for you; call it yourself only from an entry point that does not go through runConfigMode, after the configuration has loaded and before anything is written.
Types and type guards
| Export | Purpose |
|---|
OpenAPISpec, OpenAPISchema, OpenAPIParameter, OpenAPIRequestBody, OpenAPIResponse | The parts of a specification the generators read. |
HttpMethod, HTTP_METHODS | The eight HTTP methods OpenAPI defines, as a type and as a constant array. |
ExecutionMode | "parallel" | "sequential". |
BaseGeneratorOptions | The option interface every generator's options extend. |
RequireExcept<T, K> | Make every property required except the named ones. |
isObjectLike(value), isPathItemLike(value), getOperation(pathItem, method) | Guards for walking an untyped spec safely. |
OpenAPIOperationLike, PathItemLike | The structural types the guards narrow to. |
schemaToTypeString(schema), isOpenAPIParameter(value), OpenAPISchemaLike | A TypeScript type string for a schema, including 3.1 type arrays, and a parameter guard. |
Other helpers
| Export | Purpose |
|---|
ensureDirectoryExists(filePath) | Create the parent directory of an output file. |
toRelativeImportPath(fromFile, toFile) | The import specifier one generated file uses for another. |
normalizeBasePath(basePath), constructFullPath(basePath, path) | Leading slash, no trailing slash; and a base path joined to an endpoint path. |
isSuccessStatusCode(key) | Whether a response key such as 200 or 2XX denotes success. |
stringToEnumMember(value, usedKeys?), numericToEnumMember(value, usedKeys?) | Valid, de-duplicated enum member names from enum values. |
generateOperationJSDoc(options), GenerateOperationJSDocOptions | The JSDoc block the clients put above each method. |
generateFileHeader(options), generateCustomFileHeader(lines), FileHeaderOptions | The "Auto-generated by" header and the fileHeader lines above it. |