This is the first release candidate for tsoa 7. It includes everything since 7.0.0-alpha.0. Install it with npm i tsoa@next. See the upgrade guide for every change from 6.x.
Security
Hümeyra Hubacher (@meyraa) reported these issues in @tsoa/runtime and wrote the fixes. Upgrade to 7.0.0-rc.0. The first three affect only 7.0.0-alpha.0; on those, staying on 6.6.0 is also safe.
- Recursive models were not validated below the second level (#1930). Affects 7.0.0-alpha.0. The circular-reference guard returned nested elements of a recursive model unvalidated, so type checks, required properties, validators such as
@maxLength, and the removal of extra properties were skipped from the third level down. - Express routes sent returned strings as HTML (#1932). Affects 7.0.0-alpha.0. A controller that returned a string without setting a
Content-Typeansweredtext/htmlwith the string unescaped, while the spec documents JSON. A controller that returns request data, such as?q=<script>alert(1)</script>, therefore reflected it as HTML. Strings are sent as JSON again, as in 6.x. A string is sent as-is only under a non-JSONContent-Typethe controller sets. - An own
__proto__key replaced the prototype of validated union values (#1931). Affects 7.0.0-alpha.0. For a body such as{"kind":"a","__proto__":{"isAdmin":true}}, the validated value inheritedisAdmin: trueunder everynoImplicitAdditionalPropertiessetting, includingthrow-on-extras.Object.prototypewas not changed. A schema that allows extra properties still passes such a key through as plain data. - Unbounded work in buffer and array validation (#1933). Affects every release before 7.0.0-rc.0, 6.x included.
- A
Bufferparameter passed any value toBuffer.from(), so the 16-byte body{"length":1e8}allocated 100 MB. Buffers are now built only from strings, buffers, byte arrays and the JSON form of aBuffer. @uniqueItemswas quadratic: 60,000 distinct strings took over 5 s. It now takes milliseconds.@maxItemswas checked only after every element, and@maxItems 0was ignored.- An array matched an enum member with the same string form, so
["admin"]passed as"admin".
- A
Breaking changes
- Node.js 22.12 or later, 24 or 26 (#1949, @WoH). The packages declared Node.js 18 and later. Node.js 18 and 20 have reached end of life, and Fastify 5's dependencies need 22.12 on the 22 line. npm warns on other versions; Yarn 1 refuses to install.
- OpenAPI 3.1 is the default (#1948, @WoH). A
tsoa.jsonwithoutspec.specVersionnow produces an OpenAPI 3.1 spec, from the CLI and fromgenerateSpec(). Set"specVersion": 2to keep Swagger 2.0. @Queryand@Queriesare renamed to@QueryParamand@QueryParams(#1940, @WoH). There is no alias; TypeScript reports each place to change. The generated spec and routes do not change.- Framework template services moved to subpath exports (#1917, @eungkyu). Import
ExpressTemplateService,HapiTemplateServiceandKoaTemplateServicefrom@tsoa/runtime/express,@tsoa/runtime/hapiand@tsoa/runtime/koa.@tsoa/runtimeno longer installs Hapi, Koa or Express packages; they are optional peer dependencies. Routes generated by this version already use the new paths: regenerate them. multerOptsremoved (#1924, @eungkyu). It has been deprecated since 6.4.0. Pass your own instance instead:RegisterRoutes(app, { multer: multer({ dest: '/tmp' }) }). Your instance replaces the default one, including its 8 MB file size limit.@types/multeris no longer a dependency; install it yourself if your code uses multer's types.- New type resolver (#1923, @pclements12). The CLI now resolves types with the TypeScript checker. Specs can change where the old resolver produced wrong output, such as
typeoftypes, indexed access types, intrinsic string types, template literal types and inherited properties. Diff your generated spec when you upgrade. - Express peer range is
^4.22.3 || ^5.1.0(#1921, #1947). Earlier Express releases install vulnerablebody-parser,path-to-regexporqs. - Higher dependency floors (#1947): glob 14, minimatch 11, ts-deepmerge 8, handlebars 4.7.10, validator 13.15.35, yaml 2.8.3 (#1915). No version these ranges allow has a known advisory.
Features
- Fastify v5 support (#1919, @WoH). Set
routes.middlewareto"fastify"and register the generated routes withapp.register(RegisterRoutes). Uploads need@fastify/multipart9.fastifyis an optional peer dependency of@tsoa/runtime; importFastifyTemplateServicefrom@tsoa/runtime/fastify. @Queryfor the HTTPQUERYmethod from RFC 10008 (#1941, @WoH). OpenAPI 2, 3.0 and 3.1 have noqueryfield on a path item, so the spec lists the operation underx-oai-additionalOperations.- Express 5 support (#1921, @WoH). Express 5 needs
app.set('query parser', 'extended')andexpress.urlencoded({ extended: true })for bracket queries and nested form bodies. - TypeScript 6 support (#1901 by @WoH, from #1878 by @gabsong)
oneOfwithdiscriminatorfor unions of models that share a literal tag (#1884, @falk-stefan), and validation of such unions by their tag (#1906, @falk-stefan)- Optional authentication with
@Security({})(#1903, @falk-stefan) - Raw binary request bodies through
Readable(#1889, @falk-stefan) - Type aliases in
@QueryParams(#1841, @MV-GH) titlefrom the@titleannotation (#1810, @orgoro)- Compiler options are read from the project's
tsconfig.json(#1865, @joeferner)
Fixes
- Express: stream errors raised before any data go to
next(#1934, @meyraa) - Express: an optional body without bytes counts as absent (#1905 by @WoH, from #1840 by @MathieuRA)
- Streamed response failures are handled (#1861, @bigujun)
nullsurvives union aliases (#1898 by @WoH, from #1855 by @iffa)- Nested properties of generic mapped aliases are kept under
strictNullChecks(#1904 by @WoH, from #1894 by @simllll) @patternkeeps raw patterns and supports quoted spaces (#1900 by @WoH, from #1867 by @soumajitgh)- Falsy
@examplevalues such as0,falseand""are kept (#1899, @bercedev) - Empty
@returnsJSDoc tags no longer break generation (#1866, @soumajitgh) - Built-in route templates resolve when
@tsoa/cliis bundled (#1925, @hamid-digitalmarketer)