class

Analyzer::Javascript::Nestjs

Inherits Analyzer::Javascript::JavascriptEngine < Analyzer < FileHelper < Reference < Object

Constants

CONTROLLER_DECORATORS = ["Controller"]

Class decorators that open a controller and carry its path prefix. The other decorator-controller frameworks (Analyzer::Typescript::DecoratorController) name their own.

DTO_DECL_NAME = /\b(?:class|interface)\s+([A-Za-z_$][\w$]*)/
DTO_DEPTH_LIMIT = 6
DTO_PARAM_TYPES = {"Body" => "body", "Query" => "query"}
DTO_TYPE_NAME = /\A([A-Za-z_$][\w$]*)(?:\.[A-Za-z_$][\w$]*)*\s*(?:<[\s\S]*>)?\z/
GLOBAL_LITERAL_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]

Extensions worth scanning for cross-file enum/object constants — the enum may live in a .ts file even when the route-scan pass only walks .js, so cast a wide net here.

JS_SOURCE_EXT_RE = /\.[cm]?[jt]sx?$/
MIDWAY_IMPORT = "@midwayjs/"

Midway imports the same @Controller/@Get vocabulary from @midwayjs/*. Analyzer::Typescript::Midway claims those .ts files and Analyzer::Typescript::Nestjs leaves them to it; JavaScript stays with this analyzer, as there is no JS Midway analyzer.

NAMED_IMPORT = /\bimport\s+(?:type\s+)?\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/
NAMED_REEXPORT = /\bexport\s+(?:type\s+)?\{([^}]*)\}\s*from\s*['"](\.[^'"]+)['"]/
NEST_BOOTSTRAP_CALL = /\bNestFactory\s*\.\s*create\s*[<(]/
NEST_CONFIG_BASENAMES = ["nest-cli.json"]
NEST_PACKAGE_MARKERS = ["@nestjs/core", "@nestjs/common"]

Markers that identify a NestJS application root, so a prefix set in one app's bootstrap is not stamped onto another app's controllers.

NEST_PARAM_DECORATORS = [{"Query", "query", "query"}, {"Param", "path", nil}, {"Body", "body", "body"}, {"Headers", "header", "headers"}, {"HostParam", "path", nil}, {"UploadedFile", "body", "file"}, {"UploadedFiles", "body", "files"}] of Tuple(String, String, String | ::Nil)

NestJS's argument decorators in the order their params are added: the decorator, the param type, and the param one without a string argument stands for (nil: none). @Query('q') is the query param q; @Query() / @Query(pipe) the whole query.

NESTJS_BOOTSTRAP_RE = Regex.union("NestFactory.create", "from '@nestjs/core'", "from \"@nestjs/core\"", "require('@nestjs/core')", "require(\"@nestjs/core\")")

Precompiled once — a single PCRE2-JIT scan replaces five naive String#includes? substring scans over the whole file content. Regex.union auto-escapes each literal, so this is provably equivalent to the OR-of-includes? it replaces.

PROJECT_CONST_RE = /\bconst\s+([A-Za-z_$][\w$]*)\s*(?::[^=\n]+)?=\s*(\[[^\]]*\]|[^;\n]+)/

Every const NAME = <expr> in the scan, first definition wins. Version and header constants are usually imported (@calcom/platform-constants) and re-cast (VERSION_X as unknown as VersionValue), so the per-file literal table cannot see them.

REQUEST_DECORATORS = {"Req", "Request"}
REQUEST_OBJECT_FIELDS = { {"query", "query"}, {"body", "body"}, {"headers", "header"}, {"params", "path"} }

Request-object fields read in handler bodies, paired with the param type they map to. Iterated in this order when extracting params.

ROUTE_DECORATOR_METHODS = {"Get" => ["GET"], "Post" => ["POST"], "Put" => ["PUT"], "Delete" => ["DELETE"], "Del" => ["DELETE"], "Patch" => ["PATCH"], "Options" => ["OPTIONS"], "Head" => ["HEAD"], "QueryMethod" => ["QUERY"], "Sse" => ["GET"], "All" => ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]}
STAR_REEXPORT = /\bexport\s+\*\s+from\s*['"](\.[^'"]+)['"]/
STRING_ARG = /\A(['"`])([^'"`]+)\1\z/
VERSION_CONDITION = "nest:version"

Name of the route_conditions entry that carries a route's raw version list from the per-file scan to separate_header_versions.

Class methods

tech_name
Source

Instance methods

analyze
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source