@codacy/analysis-runner 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +136 -31
  2. package/dist/index.js +1598 -1129
  3. package/package.json +3 -3
package/dist/index.d.ts CHANGED
@@ -218,14 +218,54 @@ declare function readBaselineConfig(repositoryRoot: string, configFile?: string)
218
218
  * {@link resolveBaselinePath}). No `.codacy/` side effects. Callers write this
219
219
  * after every `init`/`update-config` so the next update diffs against the exact
220
220
  * generator output. Returns the path written.
221
+ *
222
+ * Config paths are relativized exactly as in {@link writeCodacyConfigFile} — the
223
+ * baseline is compared against the config it snapshots, so the two must agree on
224
+ * the stored form.
221
225
  */
222
226
  declare function writeBaselineConfig(repositoryRoot: string, config: CodacyConfig, configFile?: string): Promise<string>;
227
+ /**
228
+ * Rewrites every tool's `localConfigurationFile` to its repository-relative form,
229
+ * for serialization.
230
+ *
231
+ * Adapters detect their native config by joining `ctx.repositoryRoot`, so the
232
+ * in-memory value is absolute — and an absolute path names the machine that ran
233
+ * `init` (`/Users/someone/dev/repo/eslint.config.mjs`). Serializing it verbatim made
234
+ * `codacy.config.json` unshareable: committed and cloned elsewhere, every tool
235
+ * pointed at a directory that does not exist. The stored form is therefore relative
236
+ * (`eslint.config.mjs`), and {@link resolveLocalConfigPaths} restores absolute paths
237
+ * on read, so adapters see no difference.
238
+ *
239
+ * Returns a copy rather than mutating: `init` and `update-config` keep using the
240
+ * config object after writing it (baseline snapshot, summary output), and they need
241
+ * the resolved paths.
242
+ */
243
+ declare function relativizeLocalConfigPaths(config: CodacyConfig, repositoryRoot: string): CodacyConfig;
244
+ /**
245
+ * Resolves every stored `localConfigurationFile` against `repositoryRoot`, so
246
+ * adapters always receive an absolute path regardless of how the file on disk
247
+ * stored it.
248
+ *
249
+ * `path.resolve` covers both forms with no branching: a repo-relative path is
250
+ * joined to the root, and a legacy absolute path — written by a CLI version that
251
+ * serialized paths verbatim — is returned unchanged. Such a path is only usable on
252
+ * the machine that produced it; that is the pre-existing breakage this normalization
253
+ * stops from spreading further, not one it can repair.
254
+ *
255
+ * Mutates in place, like {@link coerceParameterValues}: both run on a config that
256
+ * was just parsed and has no other owner yet.
257
+ */
258
+ declare function resolveLocalConfigPaths(config: CodacyConfig, repositoryRoot: string): void;
223
259
  /**
224
260
  * Writes a CodacyConfig to disk at the exact resolved path, creating only the
225
261
  * parent directory. Unlike {@link writeCodacyConfig}, this has NO `.codacy/`
226
262
  * side effects, so it is safe to write to an arbitrary location (e.g. a scratch
227
263
  * config a user is experimenting with).
228
264
  *
265
+ * Per-tool `localConfigurationFile` paths are stored relative to `repositoryRoot`
266
+ * so the written file stays machine-independent — see
267
+ * {@link relativizeLocalConfigPaths}.
268
+ *
229
269
  * Pass `configFile` to write to a non-default location.
230
270
  */
231
271
  declare function writeCodacyConfigFile(repositoryRoot: string, config: CodacyConfig, configFile?: string): Promise<string>;
@@ -410,9 +450,14 @@ declare function parseAutoFilters(raw: string): {
410
450
  * The generated client (src/api/client/) is produced from the Codacy OpenAPI spec
411
451
  * and should never be edited by hand. All API interactions go through this file.
412
452
  *
413
- * Authentication: Codacy uses an `api-token` header (not Bearer). We set it via
414
- * `OpenAPI.HEADERS` before each call group. `configureApiToken()` must be called
415
- * before any authenticated endpoint is used.
453
+ * Authentication: Codacy uses an `api-token` header (account token) or a
454
+ * `project-token` header (repository token). `configureApiToken()`
455
+ * sets exactly one via `OpenAPI.HEADERS` and must be called before any
456
+ * authenticated endpoint is used. Most operations only accept `api-token`; a
457
+ * small whitelisted subset of repository-scoped reads (`getRepository`,
458
+ * `listRepositoryTools`, `listRepositoryToolPatterns`, `listIgnoredFiles`) also
459
+ * accept `project-token` — the backend rejects it everywhere else exactly as
460
+ * if no token had been sent.
416
461
  *
417
462
  * Pagination: all list endpoints use cursor-based pagination. `fetchAllPages()`
418
463
  * follows cursors until the response contains no next cursor.
@@ -428,12 +473,41 @@ interface IgnoredFilesResult {
428
473
  capped: boolean;
429
474
  }
430
475
  /**
431
- * Configures the API token used for authenticated requests.
432
- * Must be called before `getRepository`, `listRepositoryTools`, or
433
- * `listRepositoryToolPatterns`. Public endpoints (listTools, listPatterns)
434
- * do not require a token.
476
+ * Auth for API calls that accept either an account token or a repository
477
+ * (project) token — currently only the 4 reads `initRemoteConfig` makes. A
478
+ * discriminated union (same shape and naming as `UploadAuth` in `upload.ts`)
479
+ * so "exactly one token" is a compile-time guarantee, not a runtime check,
480
+ * and so there is never a "both configured" state for the backend to have to
481
+ * arbitrate — sending both was never useful anyway, since the backend always
482
+ * prefers `api-token` when both are present.
483
+ */
484
+ type RemoteAuth = {
485
+ kind: "account-token";
486
+ token: string;
487
+ } | {
488
+ kind: "repository-token";
489
+ token: string;
490
+ };
491
+ /**
492
+ * Configures the auth header used for authenticated requests. Must be called
493
+ * before `getRepository`, `listRepositoryTools`, `listRepositoryToolPatterns`,
494
+ * or `listIgnoredFiles`. Public endpoints (listTools, listPatterns) do not
495
+ * require a token.
496
+ *
497
+ * Accepts a bare account-token string, for source compatibility with this
498
+ * function's original `(token: string)` shape — this is a published package,
499
+ * and embedders (a VSCode extension, an MCP server) call it directly with a
500
+ * bare string — or a {@link RemoteAuth} object to configure a repository
501
+ * token instead. Throws if given neither a non-empty string nor a valid
502
+ * `RemoteAuth`, rather than silently configuring no auth at all.
503
+ *
504
+ * Fully replaces any previously configured auth — it does not merge with a
505
+ * prior call. A process driving multiple auth contexts (e.g. an embedder
506
+ * juggling an account token for one repository and a project token for
507
+ * another) must call this again immediately before each authenticated call
508
+ * group, the same way `initRemoteConfig` does internally.
435
509
  */
436
- declare function configureApiToken(token: string): void;
510
+ declare function configureApiToken(auth: string | RemoteAuth): void;
437
511
  /**
438
512
  * Validates an API token by calling the authenticated user endpoint.
439
513
  * Returns user info on success; caller should catch errors for invalid tokens.
@@ -447,7 +521,8 @@ declare function validateApiToken(token: string): Promise<{
447
521
  * Fetches files individually ignored in Codacy Cloud for a repository.
448
522
  * Uses cursor-based pagination capped at 10 pages (1000 files max) to avoid
449
523
  * unbounded fetching for repositories with very large ignore lists.
450
- * Requires `configureApiToken()` to have been called.
524
+ * Requires `configureApiToken()` to have been called with an account token
525
+ * or a repository (project) token — this operation accepts either.
451
526
  */
452
527
  declare function listIgnoredFiles(provider: string, org: string, repo: string): Promise<IgnoredFilesResult>;
453
528
 
@@ -557,6 +632,13 @@ interface InitRemoteStats {
557
632
  * as unsupported (cloud-only) entries (subject to the trackability filter — deprecated and
558
633
  * client-side/standalone-only tools are skipped).
559
634
  *
635
+ * @param auth - Account token or repository (project) token — a repository token alone
636
+ * is enough for all four API calls this function makes, no login required. Also
637
+ * accepts a bare account-token string, for source compatibility with callers written
638
+ * against this function's original `apiToken: string` shape — this parameter used to
639
+ * be exactly that, and this is a published package (embedders like a VSCode extension
640
+ * or MCP server call it directly), so the old call shape must keep working unchanged.
641
+ * See {@link configureApiToken} for the exact accepted shapes and validation.
560
642
  * @param onRemoteToolsFound - Optional callback invoked once after the list of enabled
561
643
  * remote tools is fetched. Receives the total count of enabled tools and the count
562
644
  * that have a registered local adapter. Fires before per-tool pattern fetching begins.
@@ -566,7 +648,7 @@ interface InitRemoteStats {
566
648
  * @param onIgnoredFilesFetched - Optional callback invoked after cloud-ignored files are
567
649
  * fetched. Receives the count and whether the 1000-file cap was reached.
568
650
  */
569
- declare function initRemoteConfig(repositoryRoot: string, provider: string, organization: string, repositoryName: string, adapters: Readonly<ToolAdapter>[], apiToken: string, onRemoteToolsFound?: (totalEnabledTools: number, matchedAdapters: number) => void, onToolProcessed?: (displayName: string, patternCount: number, usesConfigFile: boolean) => void, onIgnoredFilesFetched?: (count: number, capped: boolean) => void): Promise<{
651
+ declare function initRemoteConfig(repositoryRoot: string, provider: string, organization: string, repositoryName: string, adapters: Readonly<ToolAdapter>[], auth: string | RemoteAuth, onRemoteToolsFound?: (totalEnabledTools: number, matchedAdapters: number) => void, onToolProcessed?: (displayName: string, patternCount: number, usesConfigFile: boolean) => void, onIgnoredFilesFetched?: (count: number, capped: boolean) => void): Promise<{
570
652
  config: CodacyConfig;
571
653
  stats: InitRemoteStats;
572
654
  }>;
@@ -852,6 +934,7 @@ declare function createLogger(options?: LoggerOptions): Logger;
852
934
  *
853
935
  * All crypto uses Node.js built-in `crypto` — no external dependencies.
854
936
  */
937
+
855
938
  /**
856
939
  * Encrypts and saves an API token to ~/.codacy/credentials.
857
940
  * Creates the ~/.codacy/ directory if it doesn't exist.
@@ -876,6 +959,41 @@ declare function deleteCredentials(): Promise<boolean>;
876
959
  * 3. Throws with instructions if neither source has a token.
877
960
  */
878
961
  declare function resolveApiToken(): Promise<string>;
962
+ /**
963
+ * Resolves auth for `init --remote` / `update-config --remote`: an explicit
964
+ * repository token (`repositoryToken` argument, or `CODACY_PROJECT_TOKEN`)
965
+ * wins outright — matching `upload`'s precedence for the same flag
966
+ * (`upload.ts:87-90`) — without even attempting to resolve an account token,
967
+ * so an explicitly-scoped run never pays the cost of loading a stored login
968
+ * it didn't ask for, and is never silently re-scoped to a broader token an
969
+ * ambient `CODACY_API_TOKEN` or prior `login` happens to leave lying around.
970
+ * Only when no repository token is given does this fall back to an account
971
+ * token, read the same way {@link resolveApiToken} does (env var, then
972
+ * stored credentials) — inlined here rather than calling it, so a missing
973
+ * account token falls through to the error below instead of throwing.
974
+ */
975
+ declare function resolveRemoteAuth(repositoryToken?: string): Promise<RemoteAuth>;
976
+
977
+ /**
978
+ * Turning a raw manifest identifier into an entity.
979
+ *
980
+ * Classification is **scoped to the ecosystem the identifier came from**, with no
981
+ * global fallback. A fallback is the bug this module exists to prevent: with one
982
+ * name-keyed catalog, the sbt artifact `requests` (com.lihaoyi) matched PyPI's
983
+ * Requests, and any bare gem or crate name could borrow another language's
984
+ * package. An artifact id is only meaningful inside its own registry, so that is
985
+ * the only place it is looked up.
986
+ */
987
+
988
+ /**
989
+ * Display names of every entity discovery can emit.
990
+ *
991
+ * Kept for consumers that report on the catalog. Note it is **not** the set of
992
+ * gating keys — those are entity keys ({@link getEntityProviders}) — precisely
993
+ * because display names are not unique: Angular 2+, AngularJS and AngularDart all
994
+ * display as "Angular".
995
+ */
996
+ declare function getKnownDisplayNames(): Set<string>;
879
997
 
880
998
  /**
881
999
  * Repository discovery — scans a codebase and identifies languages, file patterns,
@@ -884,8 +1002,12 @@ declare function resolveApiToken(): Promise<string>;
884
1002
  * The discover() function is the main entry point. It runs a 4-phase pipeline:
885
1003
  * 1. File discovery (extensions, notable files)
886
1004
  * 2. Language detection (reuses detectLanguages)
887
- * 3. Manifest parsing (dependency extraction)
888
- * 4. Dependency classification (framework / library / platform / tool)
1005
+ * 3. Manifest parsing (dependency extraction, per owning ecosystem)
1006
+ * 4. Classification (raw identifier → entity, scoped to that ecosystem)
1007
+ *
1008
+ * The static knowledge behind phases 3 and 4 lives in `./ecosystems/` (one module
1009
+ * per package registry), `./signals.ts` and `./notable-files.ts`; the entity
1010
+ * vocabulary itself is in `@codacy/tooling`.
889
1011
  */
890
1012
 
891
1013
  /** Options for the discover function. */
@@ -897,7 +1019,7 @@ interface DiscoverOptions {
897
1019
  *
898
1020
  * Callers that feed discovery into configuration decisions **must** pass the
899
1021
  * same excludes `analyze` will apply (see `resolveDiscoveryExcludes` in
900
- * `./codacy-yaml`). Otherwise discovery reports languages, frameworks, and
1022
+ * `../codacy-yaml`). Otherwise discovery reports languages, frameworks, and
901
1023
  * libraries that only exist in excluded paths — e.g. a tool-orchestration
902
1024
  * monorepo whose per-language sample files all live under
903
1025
  * `**\/test/fixtures/**` looks like a 20-language polyglot repo, and every
@@ -911,23 +1033,6 @@ interface DiscoverOptions {
911
1033
  */
912
1034
  declare function discover(repositoryRoot: string, options?: DiscoverOptions): Promise<DiscoveryResult>;
913
1035
 
914
- /**
915
- * Discovery catalog — static knowledge base for the discover command.
916
- *
917
- * Contains manifest file parsers, a curated dependency classification catalog,
918
- * and notable file detection rules. All parsers are pure functions that accept
919
- * raw file content and return dependency name arrays. They never throw.
920
- */
921
-
922
- /**
923
- * Every display name discovery can emit from a dependency/file/package.json signal.
924
- * This is the authoritative set a framework-mapping key must belong to (together
925
- * with detected language names) for its patterns to ever gate on. The drift-guard
926
- * test uses it to catch mapping keys that no signal can produce (e.g. a rename
927
- * like react-intl → formatjs that updates the mapping but not the catalog).
928
- */
929
- declare function getKnownDisplayNames(): Set<string>;
930
-
931
1036
  /**
932
1037
  * Git repository introspection helpers used by commands that need to know
933
1038
  * *where* they are (repository root) and *what* they are looking at (the current
@@ -1119,4 +1224,4 @@ declare function buildPayloads(issues: NormalizedIssue[], resolveShortName: (too
1119
1224
  */
1120
1225
  declare function uploadReport(options: UploadOptions): Promise<UploadResult>;
1121
1226
 
1122
- export { type AdapterFactory, type AnalyzeOptions, type AutoFilters, type CategoryFilter, type CodacyYamlConfig, type CodacyYamlEngineConfig, type ConfigOperation, type DiscoverOptions, type DiscoveryExcludes, type ExecutionMode, type IgnoredFilesResult, type InitAutoStats, type InitDefaultStats, type InitDiscoveryOptions, type InitLocalStats, type InitRemoteStats, type LoggerOptions, type MergeOptions, type NormalizedIssue, type PatternMetadataLookup, type SeverityFilter, type UploadAuth, type UploadOptions, type UploadResult, analyze, applyCodacyYamlExcludes, applyConfigOperation, buildPayloads, buildToolConfig, clearAdapters, computePatternSummary, configureApiToken, createCodacyConfig, createLogger, createNullLogger, deleteCredentials, detectLanguages, diffConfigs, discover, formatOutput, formatTextSummary, getAdapter, getKnownDisplayNames, getRegisteredAdapters, getRegisteredDescriptors, initAutoConfig, initContainerConfig, initDefaultConfig, initLocalConfig, initRemoteConfig, intersectConfigs, listDiffFiles, listIgnoredFiles, listPrFiles, listStagedFiles, loadCredentials, mergeConfigs, parseAutoFilters, parseReport, pruneEmptyTools, readBaselineConfig, readCodacyConfig, readCodacyYaml, registerAdapter, registerLazyAdapter, registerUnsupportedTool, resolveApiToken, resolveBaselinePath, resolveConfigPath, resolveDiscoveryExcludes, resolveEngineToAdapter, resolveHeadCommit, resolveRepositoryRoot, resolveResultsApiBaseUrl, rotateLogFiles, saveCredentials, updateConfigIncremental, uploadReport, validateApiToken, writeBaselineConfig, writeCodacyConfig, writeCodacyConfigFile };
1227
+ export { type AdapterFactory, type AnalyzeOptions, type AutoFilters, type CategoryFilter, type CodacyYamlConfig, type CodacyYamlEngineConfig, type ConfigOperation, type DiscoverOptions, type DiscoveryExcludes, type ExecutionMode, type IgnoredFilesResult, type InitAutoStats, type InitDefaultStats, type InitDiscoveryOptions, type InitLocalStats, type InitRemoteStats, type LoggerOptions, type MergeOptions, type NormalizedIssue, type PatternMetadataLookup, type RemoteAuth, type SeverityFilter, type UploadAuth, type UploadOptions, type UploadResult, analyze, applyCodacyYamlExcludes, applyConfigOperation, buildPayloads, buildToolConfig, clearAdapters, computePatternSummary, configureApiToken, createCodacyConfig, createLogger, createNullLogger, deleteCredentials, detectLanguages, diffConfigs, discover, formatOutput, formatTextSummary, getAdapter, getKnownDisplayNames, getRegisteredAdapters, getRegisteredDescriptors, initAutoConfig, initContainerConfig, initDefaultConfig, initLocalConfig, initRemoteConfig, intersectConfigs, listDiffFiles, listIgnoredFiles, listPrFiles, listStagedFiles, loadCredentials, mergeConfigs, parseAutoFilters, parseReport, pruneEmptyTools, readBaselineConfig, readCodacyConfig, readCodacyYaml, registerAdapter, registerLazyAdapter, registerUnsupportedTool, relativizeLocalConfigPaths, resolveApiToken, resolveBaselinePath, resolveConfigPath, resolveDiscoveryExcludes, resolveEngineToAdapter, resolveHeadCommit, resolveLocalConfigPaths, resolveRemoteAuth, resolveRepositoryRoot, resolveResultsApiBaseUrl, rotateLogFiles, saveCredentials, updateConfigIncremental, uploadReport, validateApiToken, writeBaselineConfig, writeCodacyConfig, writeCodacyConfigFile };