fix(swagger): hoist the one inline predicate that makes the generator run away
`npm run swagger` cannot run on this tree. It dies with swagger-autogen's
"FATAL ERROR: invalid array length - Allocation failed", generating
nothing, and it reproduces on a pristine checkout under both Node 20 and
Node 24 — so the committed spec cannot be regenerated by anyone, and any
PR that adds or changes a route is unable to meet the standing obligation
to update it.
Bisected to one statement in `teams.router.js`:
param('teamId').custom((v) => v === 'default' || TEAM_ID.test(v))
Hoisting that arrow to a named const fixes it outright. Nothing else
changes and the regenerated spec is byte-identical to the committed one,
so this is a generator fix, not a spec change.
The diagnosis worth keeping, because the file's own comment recorded a
different one. Phase 8 shipped a bare regex LITERAL before `.test(` and
phase 9 hoisted the regex, blaming a per-file route limit measured at
twenty statements; the file has sat at nineteen ever since on the theory
that it was one under the edge. That theory is wrong. Probing every
router file individually, `teams.router.js` at nineteen statements dies
while a THREE-route file carrying only this one route also dies — so the
trigger is the inline arrow reaching `.test(`, not the count. Hoisting
the regex was half the fix; the predicate around it needed hoisting too.
The comments in `teams.router.js`, `teamsVoice.router.js` and
`admin/index.js` are corrected to say so, since all three currently tell
the next person to keep counting statements.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -27,13 +27,25 @@ const teamsRouter = express.Router()
|
||||
// where a Team's events leave the site for is not the §2.9 kind of decision a
|
||||
// moderator files a request for; it is deployment configuration, and it sits with
|
||||
// the role that already holds the bot token.
|
||||
// Hoisted rather than written inline, and it has to stay that way: a regex
|
||||
// LITERAL followed directly by `.test(` makes swagger-autogen's static parser run
|
||||
// away, and `npm run swagger` dies with "invalid array length — heap out of
|
||||
// memory" instead of generating a spec. Phase 8 shipped it inline and left the
|
||||
// generator unable to run at all; the same regex reached through a const (the
|
||||
// idiom `modules.router.js` already uses) parses fine.
|
||||
// Both of these are hoisted rather than written inline, and both have to stay
|
||||
// that way. **Nothing that reaches `.test(` may sit inside a route statement**:
|
||||
// swagger-autogen's static parser runs away on it and `npm run swagger` dies with
|
||||
// "invalid array length - Allocation failed", generating no spec at all.
|
||||
//
|
||||
// Two rounds of that. Phase 8 shipped the regex as a bare LITERAL before `.test(`
|
||||
// and phase 9 hoisted it — but left the PREDICATE inline, which is the same
|
||||
// runaway even with the regex behind a const, and the generator stayed broken.
|
||||
// Bisected to exactly the `param('teamId').custom(...)` statement below: a
|
||||
// three-route file carrying only it dies, so this is not about how much is in the
|
||||
// file.
|
||||
//
|
||||
// That last point corrects what this file used to say. Phase 9 read the symptom
|
||||
// as a per-file ROUTE LIMIT, measured it at twenty `teamsRouter.*` statements,
|
||||
// split `teamsVoice.router.js` out and left this file sitting at nineteen "one
|
||||
// under the edge". There is no such edge to sit under — the count was a proxy for
|
||||
// how much text the parser chewed before hitting the real trigger.
|
||||
const TEAM_ID = /^[0-9]+$/
|
||||
const isTeamIdOrDefault = (v) => v === 'default' || TEAM_ID.test(v)
|
||||
|
||||
const adminOnly = requireRole('admin')
|
||||
|
||||
@@ -181,7 +193,7 @@ teamsRouter.delete(
|
||||
/* #swagger.responses[200] = { description: 'Removed', content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponse" } } } } */
|
||||
/* #swagger.responses[404] = { description: 'Nothing configured for that Team', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
|
||||
adminOnly,
|
||||
param('teamId').custom((v) => v === 'default' || TEAM_ID.test(v)),
|
||||
param('teamId').custom(isTeamIdOrDefault),
|
||||
validate,
|
||||
ctrl.deleteIntegrationConfig,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user