module
Noir::LocatorKeys
Overview
Every slot in CodeLocator, declared once.
The table below is the registry: the constants, the per-phase reset lists,
and spec/unit_test/models/locator_keys_spec.cr are all generated from it,
so a key cannot exist without a lifecycle and a lifecycle cannot be
declared for a key nothing uses.
Fields: {CONSTANT, name, :array | :single, lifecycle, owning subsystem}.
Every one of these is written by the detector pass and drained during
analysis, which is what :detect_scoped means — see
LocatorKey::Lifecycle. The runtime-minted Express family below is the
only :analyze_scoped slot.
Defined in:
models/locator_keys.crConstant Summary
-
ANDROID_ASSETLINKS =
::Noir::LocatorKey(Array(String)).new("android-assetlinks", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/mobile/well_known") -
ANDROID_MANIFEST =
::Noir::LocatorKey(Array(String)).new("android-manifest", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/mobile/android") -
APACHE_HTTPD_SPEC =
::Noir::LocatorKey(Array(String)).new("apache-httpd-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/apache_httpd") -
APISIX_JSON =
::Noir::LocatorKey(Array(String)).new("apisix-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/apisix") -
APISIX_YAML =
::Noir::LocatorKey(Array(String)).new("apisix-yaml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/apisix") -
APPWRITE_CONFIG =
::Noir::LocatorKey(Array(String)).new("appwrite-config", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/appwrite") -
ARRAY_KEYS =
[ANDROID_ASSETLINKS, ANDROID_MANIFEST, APACHE_HTTPD_SPEC, APISIX_JSON, APISIX_YAML, APPWRITE_CONFIG, ASYNCAPI_JSON, ASYNCAPI_YAML, AWS_CDK_SPEC, AWS_CLOUDFORMATION_SPEC, AZURE_FUNCTIONS_SPEC, BRUNO_BRU, BURP_SITEMAP, CADDY_SPEC, CAIDO_JSON, CLOUDFLARE_WRANGLER_SPEC, DIRECTUS_SNAPSHOT, ENVOY_JSON, ENVOY_YAML, GRAPHQL_SDL, GRPC_PROTO, HAR_PATH, HASURA_REST_ENDPOINTS, HASURA_TABLES, HTTP_FILE, INSOMNIA_JSON, INSOMNIA_YAML, IOS_AASA, IOS_ENTITLEMENTS, IOS_INFO_PLIST, ISTIO_VIRTUALSERVICE_SPEC, K8S_GATEWAY_API_SPEC, K8S_INGRESS_SPEC, KAMAL_SPEC, KONG_SPEC, MITMPROXY_PATH, NETLIFY_REDIRECTS, NETLIFY_TOML, NGINX_SPEC, OAS3_JSON, OAS3_YAML, ODATA_SPEC, OPENRPC_JSON, PAYLOAD_COLLECTION, PAYLOAD_CONFIG, PAYLOAD_GLOBAL, POSTMAN_JSON, RAML_SPEC, SERVERLESS_FRAMEWORK_SPEC, SMITHY_SPEC, STRAPI_ROUTES, STRAPI_SCHEMA, SUPABASE_CONFIG, SUPABASE_MIGRATION, SWAGGER_JSON, SWAGGER_YAML, TERRAFORM_SPEC, TRAEFIK_SPEC, TYPESPEC_SPEC, VERCEL_SPEC, WSDL_SPEC, ZAP_SITES_TREE] of ::Noir::LocatorKey(Array(String)) -
The array literals are what force the constants above into existence. Do not "simplify" this into per-constant registration side effects: Crystal may elide an unused constant's initializer, and the reset lists would silently come up short.
-
ASYNCAPI_JSON =
::Noir::LocatorKey(Array(String)).new("asyncapi-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/asyncapi") -
ASYNCAPI_YAML =
::Noir::LocatorKey(Array(String)).new("asyncapi-yaml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/asyncapi") -
AWS_CDK_SPEC =
::Noir::LocatorKey(Array(String)).new("aws-cdk-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/aws_cdk") -
AWS_CLOUDFORMATION_SPEC =
::Noir::LocatorKey(Array(String)).new("aws-cloudformation-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/aws_cloudformation") -
AZURE_FUNCTIONS_SPEC =
::Noir::LocatorKey(Array(String)).new("azure-functions-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/azure_functions") -
BRUNO_BRU =
::Noir::LocatorKey(Array(String)).new("bruno-bru", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/bruno") -
BURP_SITEMAP =
::Noir::LocatorKey(Array(String)).new("burp-sitemap", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/burp") -
CADDY_SPEC =
::Noir::LocatorKey(Array(String)).new("caddy-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/caddy") -
CAIDO_JSON =
::Noir::LocatorKey(Array(String)).new("caido-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/caido") -
CLOUDFLARE_WRANGLER_SPEC =
::Noir::LocatorKey(Array(String)).new("cloudflare-wrangler-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/cloudflare_wrangler") -
CS_APINET_MVC_ROUTECONFIG =
::Noir::LocatorKey(String).new("cs-apinet-mvc-routeconfig", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/csharp/aspnet_mvc") -
DECLARATIONS =
[{:ANDROID_ASSETLINKS, "android-assetlinks", :array, :detect_scoped, "detector/mobile/well_known"}, {:ANDROID_MANIFEST, "android-manifest", :array, :detect_scoped, "detector/mobile/android"}, {:APACHE_HTTPD_SPEC, "apache-httpd-spec", :array, :detect_scoped, "detector/specification/apache_httpd"}, {:APISIX_JSON, "apisix-json", :array, :detect_scoped, "detector/specification/apisix"}, {:APISIX_YAML, "apisix-yaml", :array, :detect_scoped, "detector/specification/apisix"}, {:APPWRITE_CONFIG, "appwrite-config", :array, :detect_scoped, "detector/specification/appwrite"}, {:ASYNCAPI_JSON, "asyncapi-json", :array, :detect_scoped, "detector/specification/asyncapi"}, {:ASYNCAPI_YAML, "asyncapi-yaml", :array, :detect_scoped, "detector/specification/asyncapi"}, {:AWS_CDK_SPEC, "aws-cdk-spec", :array, :detect_scoped, "detector/specification/aws_cdk"}, {:AWS_CLOUDFORMATION_SPEC, "aws-cloudformation-spec", :array, :detect_scoped, "detector/specification/aws_cloudformation"}, {:AZURE_FUNCTIONS_SPEC, "azure-functions-spec", :array, :detect_scoped, "detector/specification/azure_functions"}, {:BRUNO_BRU, "bruno-bru", :array, :detect_scoped, "detector/specification/bruno"}, {:BURP_SITEMAP, "burp-sitemap", :array, :detect_scoped, "detector/specification/burp"}, {:CADDY_SPEC, "caddy-spec", :array, :detect_scoped, "detector/specification/caddy"}, {:CAIDO_JSON, "caido-json", :array, :detect_scoped, "detector/specification/caido"}, {:CLOUDFLARE_WRANGLER_SPEC, "cloudflare-wrangler-spec", :array, :detect_scoped, "detector/specification/cloudflare_wrangler"}, {:CS_APINET_MVC_ROUTECONFIG, "cs-apinet-mvc-routeconfig", :single, :detect_scoped, "detector/csharp/aspnet_mvc"}, {:DIRECTUS_SNAPSHOT, "directus-snapshot", :array, :detect_scoped, "detector/specification/directus"}, {:ENVOY_JSON, "envoy-json", :array, :detect_scoped, "detector/specification/envoy"}, {:ENVOY_YAML, "envoy-yaml", :array, :detect_scoped, "detector/specification/envoy"}, {:GRAPHQL_SDL, "graphql-sdl", :array, :detect_scoped, "detector/specification/graphql_sdl"}, {:GRPC_PROTO, "grpc-proto", :array, :detect_scoped, "detector/specification/grpc"}, {:HAR_PATH, "har-path", :array, :detect_scoped, "detector/specification/har"}, {:HASURA_REST_ENDPOINTS, "hasura-rest-endpoints", :array, :detect_scoped, "detector/specification/hasura"}, {:HASURA_TABLES, "hasura-tables", :array, :detect_scoped, "detector/specification/hasura"}, {:HTTP_FILE, "http-file", :array, :detect_scoped, "detector/specification/http_file"}, {:INSOMNIA_JSON, "insomnia-json", :array, :detect_scoped, "detector/specification/insomnia"}, {:INSOMNIA_YAML, "insomnia-yaml", :array, :detect_scoped, "detector/specification/insomnia"}, {:IOS_AASA, "ios-aasa", :array, :detect_scoped, "detector/mobile/well_known"}, {:IOS_ENTITLEMENTS, "ios-entitlements", :array, :detect_scoped, "detector/mobile/ios"}, {:IOS_INFO_PLIST, "ios-info-plist", :array, :detect_scoped, "detector/mobile/ios"}, {:ISTIO_VIRTUALSERVICE_SPEC, "istio-virtualservice-spec", :array, :detect_scoped, "detector/specification/istio_virtualservice"}, {:K8S_GATEWAY_API_SPEC, "k8s-gateway-api-spec", :array, :detect_scoped, "detector/specification/k8s_gateway_api"}, {:K8S_INGRESS_SPEC, "k8s-ingress-spec", :array, :detect_scoped, "detector/specification/k8s_ingress"}, {:KAMAL_SPEC, "kamal-spec", :array, :detect_scoped, "detector/specification/kamal"}, {:KONG_SPEC, "kong-spec", :array, :detect_scoped, "detector/specification/kong"}, {:MITMPROXY_PATH, "mitmproxy-path", :array, :detect_scoped, "detector/specification/mitmproxy"}, {:NETLIFY_REDIRECTS, "netlify-redirects", :array, :detect_scoped, "detector/specification/netlify"}, {:NETLIFY_TOML, "netlify-toml", :array, :detect_scoped, "detector/specification/netlify"}, {:NGINX_SPEC, "nginx-spec", :array, :detect_scoped, "detector/specification/nginx"}, {:OAS3_JSON, "oas3-json", :array, :detect_scoped, "detector/specification/oas3"}, {:OAS3_YAML, "oas3-yaml", :array, :detect_scoped, "detector/specification/oas3"}, {:ODATA_SPEC, "odata-spec", :array, :detect_scoped, "detector/specification/odata"}, {:OPENRPC_JSON, "openrpc-json", :array, :detect_scoped, "detector/specification/openrpc"}, {:PAYLOAD_COLLECTION, "payload-collection", :array, :detect_scoped, "detector/specification/payload_cms"}, {:PAYLOAD_CONFIG, "payload-config", :array, :detect_scoped, "detector/specification/payload_cms"}, {:PAYLOAD_GLOBAL, "payload-global", :array, :detect_scoped, "detector/specification/payload_cms"}, {:POSTMAN_JSON, "postman-json", :array, :detect_scoped, "detector/specification/postman"}, {:RAML_SPEC, "raml-spec", :array, :detect_scoped, "detector/specification/raml"}, {:SERVERLESS_FRAMEWORK_SPEC, "serverless-framework-spec", :array, :detect_scoped, "detector/specification/serverless_framework"}, {:SMITHY_SPEC, "smithy-spec", :array, :detect_scoped, "detector/specification/smithy"}, {:STRAPI_ROUTES, "strapi-routes", :array, :detect_scoped, "detector/specification/strapi"}, {:STRAPI_SCHEMA, "strapi-schema", :array, :detect_scoped, "detector/specification/strapi"}, {:SUPABASE_CONFIG, "supabase-config", :array, :detect_scoped, "detector/specification/supabase"}, {:SUPABASE_MIGRATION, "supabase-migration", :array, :detect_scoped, "detector/specification/supabase"}, {:SWAGGER_JSON, "swagger-json", :array, :detect_scoped, "detector/specification/oas2"}, {:SWAGGER_YAML, "swagger-yaml", :array, :detect_scoped, "detector/specification/oas2"}, {:TERRAFORM_SPEC, "terraform-spec", :array, :detect_scoped, "detector/specification/terraform"}, {:TRAEFIK_SPEC, "traefik-spec", :array, :detect_scoped, "detector/specification/traefik"}, {:TYPESPEC_SPEC, "typespec-spec", :array, :detect_scoped, "detector/specification/typespec"}, {:VERCEL_SPEC, "vercel-spec", :array, :detect_scoped, "detector/specification/vercel"}, {:WSDL_SPEC, "wsdl-spec", :array, :detect_scoped, "detector/specification/wsdl"}, {:ZAP_SITES_TREE, "zap-sites-tree", :array, :detect_scoped, "detector/specification/zap_sites_tree"}] -
DIRECTUS_SNAPSHOT =
::Noir::LocatorKey(Array(String)).new("directus-snapshot", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/directus") -
ENVOY_JSON =
::Noir::LocatorKey(Array(String)).new("envoy-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/envoy") -
ENVOY_YAML =
::Noir::LocatorKey(Array(String)).new("envoy-yaml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/envoy") -
EXPRESS_ROUTER_PREFIX =
::Noir::LocatorKeyNamespace.new("express_router_prefix", ::Noir::LocatorKey::Lifecycle::AnalyzeScoped, "analyzer/javascript") -
Runtime-minted key family:
express_router_prefix:<file>[:<function>].The prose above this declaration always said "written by the Express router-mount scanner and by Koa", but the
ownerfield saidanalyzer/javascript/express— which coversexpress.crandexpress/router_mount_scanner.crand excludeskoa.cr. The comment and the metadata disagreed, and nothing checked the metadata beyond it being non-blank, so the field that exists to answer "who writes this slot" was the one place in the typed-key registry that was wrong.The owner is the JavaScript analyzer family, which is what both writers actually are. They mint through
ExpressConstants.file_key/.function_key, andNoir::JSRouteExtractorreads it — two analyzers and a shared extractor, none of which is "express" specifically.spec/unit_test/models/locator_ownership_spec.crnow verifies this against the source rather than trusting it. -
GRAPHQL_SDL =
::Noir::LocatorKey(Array(String)).new("graphql-sdl", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/graphql_sdl") -
GRPC_PROTO =
::Noir::LocatorKey(Array(String)).new("grpc-proto", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/grpc") -
HAR_PATH =
::Noir::LocatorKey(Array(String)).new("har-path", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/har") -
HASURA_REST_ENDPOINTS =
::Noir::LocatorKey(Array(String)).new("hasura-rest-endpoints", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/hasura") -
HASURA_TABLES =
::Noir::LocatorKey(Array(String)).new("hasura-tables", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/hasura") -
HTTP_FILE =
::Noir::LocatorKey(Array(String)).new("http-file", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/http_file") -
INSOMNIA_JSON =
::Noir::LocatorKey(Array(String)).new("insomnia-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/insomnia") -
INSOMNIA_YAML =
::Noir::LocatorKey(Array(String)).new("insomnia-yaml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/insomnia") -
IOS_AASA =
::Noir::LocatorKey(Array(String)).new("ios-aasa", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/mobile/well_known") -
IOS_ENTITLEMENTS =
::Noir::LocatorKey(Array(String)).new("ios-entitlements", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/mobile/ios") -
IOS_INFO_PLIST =
::Noir::LocatorKey(Array(String)).new("ios-info-plist", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/mobile/ios") -
ISTIO_VIRTUALSERVICE_SPEC =
::Noir::LocatorKey(Array(String)).new("istio-virtualservice-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/istio_virtualservice") -
K8S_GATEWAY_API_SPEC =
::Noir::LocatorKey(Array(String)).new("k8s-gateway-api-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/k8s_gateway_api") -
K8S_INGRESS_SPEC =
::Noir::LocatorKey(Array(String)).new("k8s-ingress-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/k8s_ingress") -
KAMAL_SPEC =
::Noir::LocatorKey(Array(String)).new("kamal-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/kamal") -
KONG_SPEC =
::Noir::LocatorKey(Array(String)).new("kong-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/kong") -
MITMPROXY_PATH =
::Noir::LocatorKey(Array(String)).new("mitmproxy-path", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/mitmproxy") -
NAMESPACES =
[EXPRESS_ROUTER_PREFIX] -
NETLIFY_REDIRECTS =
::Noir::LocatorKey(Array(String)).new("netlify-redirects", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/netlify") -
NETLIFY_TOML =
::Noir::LocatorKey(Array(String)).new("netlify-toml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/netlify") -
NGINX_SPEC =
::Noir::LocatorKey(Array(String)).new("nginx-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/nginx") -
OAS3_JSON =
::Noir::LocatorKey(Array(String)).new("oas3-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/oas3") -
OAS3_YAML =
::Noir::LocatorKey(Array(String)).new("oas3-yaml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/oas3") -
ODATA_SPEC =
::Noir::LocatorKey(Array(String)).new("odata-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/odata") -
OPENRPC_JSON =
::Noir::LocatorKey(Array(String)).new("openrpc-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/openrpc") -
PAYLOAD_COLLECTION =
::Noir::LocatorKey(Array(String)).new("payload-collection", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/payload_cms") -
PAYLOAD_CONFIG =
::Noir::LocatorKey(Array(String)).new("payload-config", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/payload_cms") -
PAYLOAD_GLOBAL =
::Noir::LocatorKey(Array(String)).new("payload-global", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/payload_cms") -
POSTMAN_JSON =
::Noir::LocatorKey(Array(String)).new("postman-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/postman") -
RAML_SPEC =
::Noir::LocatorKey(Array(String)).new("raml-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/raml") -
SERVERLESS_FRAMEWORK_SPEC =
::Noir::LocatorKey(Array(String)).new("serverless-framework-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/serverless_framework") -
SINGLE_KEYS =
[CS_APINET_MVC_ROUTECONFIG] of ::Noir::LocatorKey(String) -
SMITHY_SPEC =
::Noir::LocatorKey(Array(String)).new("smithy-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/smithy") -
STRAPI_ROUTES =
::Noir::LocatorKey(Array(String)).new("strapi-routes", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/strapi") -
STRAPI_SCHEMA =
::Noir::LocatorKey(Array(String)).new("strapi-schema", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/strapi") -
SUPABASE_CONFIG =
::Noir::LocatorKey(Array(String)).new("supabase-config", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/supabase") -
SUPABASE_MIGRATION =
::Noir::LocatorKey(Array(String)).new("supabase-migration", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/supabase") -
SWAGGER_JSON =
::Noir::LocatorKey(Array(String)).new("swagger-json", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/oas2") -
SWAGGER_YAML =
::Noir::LocatorKey(Array(String)).new("swagger-yaml", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/oas2") -
TERRAFORM_SPEC =
::Noir::LocatorKey(Array(String)).new("terraform-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/terraform") -
TRAEFIK_SPEC =
::Noir::LocatorKey(Array(String)).new("traefik-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/traefik") -
TYPESPEC_SPEC =
::Noir::LocatorKey(Array(String)).new("typespec-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/typespec") -
VERCEL_SPEC =
::Noir::LocatorKey(Array(String)).new("vercel-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/vercel") -
WSDL_SPEC =
::Noir::LocatorKey(Array(String)).new("wsdl-spec", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/wsdl") -
ZAP_SITES_TREE =
::Noir::LocatorKey(Array(String)).new("zap-sites-tree", ::Noir::LocatorKey::Lifecycle::DetectScoped, "detector/specification/zap_sites_tree")
Class Method Summary
-
.reset(phase : Noir::LocatorKey::Lifecycle) : Nil
Drop everything
phaseowns.
Class Method Detail
Drop everything phase owns.
Called at the top of the phase, before it writes anything, so a second
scan in the same process cannot read the first one's registrations. This
replaces a hand-written list at the top of detect_techs that named six
of the 64 keys — the other 58 were never cleared at all, which is why
SpecificationEngine#each_spec_file needed a File.exists? guard to
avoid reading a previous scan's paths.
The phases are separate on purpose. Detector-written keys are drained during analysis, so clearing them at analysis start would destroy the scan; the Express keys are written and read inside one analysis pass and must not survive into the next.