ng-checkup 0.9.1 → 0.10.1
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.
- package/README.md +40 -7
- package/dist/angularjs.d.ts +136 -0
- package/dist/angularjs.js +292 -0
- package/dist/angularjs.js.map +1 -0
- package/dist/cache.d.ts +8 -2
- package/dist/cache.js +3 -3
- package/dist/cache.js.map +1 -1
- package/dist/checks/angularjs.d.ts +98 -0
- package/dist/checks/angularjs.js +284 -0
- package/dist/checks/angularjs.js.map +1 -0
- package/dist/checks/change-detection.js +3 -1
- package/dist/checks/change-detection.js.map +1 -1
- package/dist/checks/circular-deps.js +6 -1
- package/dist/checks/circular-deps.js.map +1 -1
- package/dist/checks/context.d.ts +3 -0
- package/dist/checks/context.js.map +1 -1
- package/dist/checks/version.js +3 -1
- package/dist/checks/version.js.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/files.d.ts +7 -0
- package/dist/files.js +24 -6
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +19 -5
- package/dist/index.js.map +1 -1
- package/dist/migration.d.ts +40 -0
- package/dist/migration.js +116 -0
- package/dist/migration.js.map +1 -0
- package/dist/report/html.js +49 -6
- package/dist/report/html.js.map +1 -1
- package/dist/report/markdown.js +10 -0
- package/dist/report/markdown.js.map +1 -1
- package/dist/report/notes.d.ts +2 -1
- package/dist/report/notes.js +4 -1
- package/dist/report/notes.js.map +1 -1
- package/dist/report/terminal.js +10 -0
- package/dist/report/terminal.js.map +1 -1
- package/dist/scan.d.ts +6 -3
- package/dist/scan.js +9 -4
- package/dist/scan.js.map +1 -1
- package/dist/template-text.d.ts +12 -0
- package/dist/template-text.js +17 -0
- package/dist/template-text.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/watch.js +1 -1
- package/dist/watch.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**A one-minute modernization report for any Angular codebase.**
|
|
6
6
|
|
|
7
|
-
Point it at a repository and it tells you how far the code is from current Angular, what will break on the next upgrade, and where the work is. Twelve areas get a grade, from the Angular version and third-party packages to security and bundle size, every finding names the files, and the HTML report is one self-contained page you can hand to your team lead.
|
|
7
|
+
Point it at a repository and it tells you how far the code is from current Angular, what will break on the next upgrade, and where the work is. Twelve areas get a grade, from the Angular version and third-party packages to security and bundle size (and a thirteenth for AngularJS code still waiting to be migrated), every finding names the files, and the HTML report is one self-contained page you can hand to your team lead.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npx ng-checkup
|
|
@@ -24,6 +24,7 @@ npx ng-checkup
|
|
|
24
24
|
- [Baseline: adopt it on legacy code](#baseline-adopt-it-on-legacy-code)
|
|
25
25
|
- [Watch mode](#watch-mode)
|
|
26
26
|
- [Upgrade plan](#upgrade-plan)
|
|
27
|
+
- [AngularJS and hybrid apps](#angularjs-and-hybrid-apps)
|
|
27
28
|
- [Monorepos](#monorepos)
|
|
28
29
|
- [Client report](#client-report)
|
|
29
30
|
- [What it checks](#what-it-checks)
|
|
@@ -184,6 +185,28 @@ Upgrade plan 12 → 22, 10 steps, one major at a time
|
|
|
184
185
|
|
|
185
186
|
The plan is in every format, including the HTML report ([example](https://stefankuburovic.github.io/ng-checkup/example.html#plan-title)) and the JSON (`report.plan`).
|
|
186
187
|
|
|
188
|
+
## AngularJS and hybrid apps
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npx ng-checkup github:orientechnologies/orientdb-studio --plan
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
When a repository still has AngularJS (1.x), a thirteenth area comes first in the report, **AngularJS migration**. It reads the JavaScript as well as the TypeScript, in every registration style real apps use (`angular.module('app').component(…)` chains, modules held in variables, ES-module AngularJS), and counts what there is to move: components, directives and controllers, services, filters, and templates with AngularJS syntax. It names what makes a piece hard to move: controllers and `ng-controller`, `$scope`, scope events used as a message bus, runtime `$compile`, `$watch`, `ng-include`, and directives using `compile`, `replace` or `terminal`, which `UpgradeComponent` cannot wrap. AngularJS packages get their Angular replacement (`angular-route`, `angular-translate`, AngularJS Material, ...), and the version comes from `package.json`, the lockfile, `bower.json`, a CDN script tag or a checked-in `angular.js`.
|
|
195
|
+
|
|
196
|
+
In a **hybrid** app (`UpgradeModule`, `downgradeModule` or the old `UpgradeAdapter`) it measures how far the migration has come: the share of components already on Angular, and what crosses the border in each direction. An Angular class registered for AngularJS with `downgradeComponent` or `downgradeInjectable` counts as migrated.
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
[POOR] AngularJS migration Hybrid AngularJS 1.5.9 and Angular 4: 35% of components on Angular, 115 AngularJS components left.
|
|
200
|
+
high AngularJS 1.5.9 is end of life since January 2022
|
|
201
|
+
medium 88 controllers registered with `.controller()`, 83 bound with `ng-controller`
|
|
202
|
+
medium 5 directives use `compile`, `replace` or `terminal`
|
|
203
|
+
medium 64 scope events (`$broadcast`, `$emit`, `$rootScope.$on`) used as a message bus
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
With `--plan` the report adds the **migration plan**, in the order of the Angular upgrade guide and with this codebase's counts on every item: prepare on AngularJS (1.8, TypeScript, controllers to components, state off `$scope`), run Angular next to AngularJS, move the code bottom up (services, filters, components, templates, packages), remove AngularJS. A hybrid app on an old Angular gets the Angular upgrade plan next to it, and the client report puts both in its roadmap.
|
|
207
|
+
|
|
208
|
+
Every count is a [measure](https://github.com/stefankuburovic/ng-checkup/blob/main/docs/checks.md#measures), so a [baseline](#baseline-adopt-it-on-legacy-code) in CI holds a running migration to one rule: AngularJS only ever shrinks.
|
|
209
|
+
|
|
187
210
|
## Monorepos
|
|
188
211
|
|
|
189
212
|
In an Angular CLI workspace with several projects or an Nx workspace, the report adds a table with one row per project, worst score first (here [nx-examples](https://github.com/nrwl/nx-examples), shortened):
|
|
@@ -224,6 +247,7 @@ The codebase is named by its repository and commit, never by a path on your disk
|
|
|
224
247
|
|
|
225
248
|
| Area | It looks at | Poor when |
|
|
226
249
|
| --- | --- | --- |
|
|
250
|
+
| [**AngularJS migration**](https://github.com/stefankuburovic/ng-checkup/blob/main/docs/checks.md#angularjs) (only with AngularJS code or packages) | AngularJS components, directives, controllers, services, filters and templates; `$scope`, scope events, `$compile`, directives `UpgradeComponent` cannot wrap; AngularJS packages; hybrid progress | any AngularJS code left, unless a hybrid app has 80% of its components on Angular |
|
|
227
251
|
| [**Angular version & tooling**](https://github.com/stefankuburovic/ng-checkup/blob/main/docs/checks.md#version) | installed vs. latest Angular, mixed `@angular/*` majors, webpack builder, end-of-life packages | three or more majors behind, i.e. out of support |
|
|
228
252
|
| [**Deprecated APIs**](https://github.com/stefankuburovic/ng-checkup/blob/main/docs/checks.md#deprecated-apis) | every imported Angular/NgRx symbol your **installed** version tags `@deprecated`, plus `*ngIf` / `*ngFor` in templates | something deprecated two majors ago is still used |
|
|
229
253
|
| [**Third-party compatibility**](https://github.com/stefankuburovic/ng-checkup/blob/main/docs/checks.md#dependencies) | the `@angular/core` peer range of every installed package (PrimeNG, Kendo, ng-bootstrap, NGXS, ...), the release that supports the next majors, npm deprecations | a package does not accept the installed Angular, or no release supports the latest |
|
|
@@ -282,7 +306,8 @@ Options:
|
|
|
282
306
|
--json Print the report as JSON to stdout instead of the summary
|
|
283
307
|
-v, --verbose Print every finding with its files
|
|
284
308
|
--plan Add an upgrade plan to the latest Angular, one major
|
|
285
|
-
at a time, with the migrations this code needs
|
|
309
|
+
at a time, with the migrations this code needs, and
|
|
310
|
+
the migration plan for AngularJS code
|
|
286
311
|
-p, --project <name> Analyse one project of an Angular CLI or Nx workspace.
|
|
287
312
|
Without it, a multi-project workspace also gets a
|
|
288
313
|
per-project table
|
|
@@ -321,7 +346,7 @@ Exit codes: `0` done, `1` `--fail-on` tripped, `2` usage error (including `--fai
|
|
|
321
346
|
|
|
322
347
|
## In CI
|
|
323
348
|
|
|
324
|
-
**GitHub Action
|
|
349
|
+
**GitHub Action** ([on the Marketplace](https://github.com/marketplace/actions/ng-checkup)). One comment on every pull request, edited in place on each push, with what got worse or better than the baseline, a grade per area and the top priorities. Plus the job summary, the full reports as an artifact, and optionally annotations on the changed lines:
|
|
325
350
|
|
|
326
351
|
```yaml
|
|
327
352
|
name: ng-checkup
|
|
@@ -360,7 +385,16 @@ No `npm ci` needed: versions come from the lockfile. Inputs: `path` (a folder in
|
|
|
360
385
|
path: checkup.*
|
|
361
386
|
```
|
|
362
387
|
|
|
363
|
-
**GitLab CI.** One include gives merge requests the same: the findings in the Code Quality widget, where GitLab lists what the MR introduces and what it resolves against the target branch (on every tier, self-hosted included), the reports as artifacts, and one comment on the merge request, edited on every push:
|
|
388
|
+
**GitLab CI.** One include gives merge requests the same: the findings in the Code Quality widget, where GitLab lists what the MR introduces and what it resolves against the target branch (on every tier, self-hosted included), the reports as artifacts, and one comment on the merge request, edited on every push. On gitlab.com, use the [CI/CD Catalog component](https://gitlab.com/explore/catalog/stefankuburovic/ng-checkup), configured through inputs (`path`, `fail-on`, `args`, `job-name` for one checkup per app, ...):
|
|
389
|
+
|
|
390
|
+
```yaml
|
|
391
|
+
include:
|
|
392
|
+
- component: $CI_SERVER_FQDN/stefankuburovic/ng-checkup/ng-checkup@0.10.0
|
|
393
|
+
inputs:
|
|
394
|
+
fail-on: regression
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
On a self-managed GitLab, which cannot include components from gitlab.com, use the template:
|
|
364
398
|
|
|
365
399
|
```yaml
|
|
366
400
|
include:
|
|
@@ -371,7 +405,7 @@ ng-checkup:
|
|
|
371
405
|
NG_CHECKUP_FAIL_ON: regression # optional; also NG_CHECKUP_PATH, NG_CHECKUP_ARGS
|
|
372
406
|
```
|
|
373
407
|
|
|
374
|
-
The job runs on merge requests and on the default branch, which is what the widget compares with. For the comment, add a
|
|
408
|
+
The job runs on merge requests and on the default branch, which is what the widget compares with. For the comment, add a token with the `api` scope as the CI/CD variable `NG_CHECKUP_TOKEN`, **masked but not protected** (merge request branches are not protected, so a protected variable never reaches them). A project access token comments as a bot; on gitlab.com Free, where those need Premium, a personal access token works and comments as you. GitLab's own job token cannot write comments, so without the variable the comment is skipped and the rest runs. A live example: [ng-checkup-demo](https://gitlab.com/stefankuburovic/ng-checkup-demo). `npx ng-checkup init` writes this for a repository with a `.gitlab-ci.yml`. If your GitLab cannot reach GitHub, copy [`gitlab/ng-checkup.yml`](https://github.com/stefankuburovic/ng-checkup/blob/main/gitlab/ng-checkup.yml) into the repository and include it with `local:`.
|
|
375
409
|
|
|
376
410
|
**GitHub code scanning**
|
|
377
411
|
|
|
@@ -441,12 +475,11 @@ Package names and versions, and only to the public npm registry: the latest `@an
|
|
|
441
475
|
|
|
442
476
|
**Why is bundle size "info"?** It reads the stats file of your last build instead of running one. `ng build --stats-json` writes it; run the checkup after that.
|
|
443
477
|
|
|
444
|
-
**Which Angular versions?** Angular 2 and newer
|
|
478
|
+
**Which Angular versions?** Angular 2 and newer, and AngularJS 1.x on its way there: AngularJS code gets its own area and a [migration plan](#angularjs-and-hybrid-apps). Checks whose rules changed between versions (standalone, OnPush, zoneless defaults) apply the rules of the version you run.
|
|
445
479
|
|
|
446
480
|
## Roadmap
|
|
447
481
|
|
|
448
482
|
- Per-project baselines for monorepos
|
|
449
|
-
- The Action on the GitHub Marketplace
|
|
450
483
|
- Change frequency from git history, to rank large files by how often they change
|
|
451
484
|
- A VS Code extension showing findings inline
|
|
452
485
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/** The AngularJS registration methods that define something a migration has to move. */
|
|
2
|
+
export type RegistrationKind = 'component' | 'directive' | 'controller' | 'service' | 'factory' | 'provider' | 'filter';
|
|
3
|
+
/** One `.controller('Name', …)`, `.component('name', …)` and so on. */
|
|
4
|
+
export interface Registration {
|
|
5
|
+
kind: RegistrationKind;
|
|
6
|
+
name: string;
|
|
7
|
+
line: number;
|
|
8
|
+
/**
|
|
9
|
+
* True when the call chain starts at `angular.module(…)`, directly or
|
|
10
|
+
* through a variable this file assigned from it. False for `app.controller()`
|
|
11
|
+
* on a module that came from somewhere else, which is only counted when the
|
|
12
|
+
* repository shows other AngularJS evidence: Vue registers components,
|
|
13
|
+
* directives and filters with the same call shape.
|
|
14
|
+
*/
|
|
15
|
+
rooted: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* True for `.factory('X', downgradeInjectable(X))` and
|
|
18
|
+
* `.directive('x', downgradeComponent(…))`: an Angular class made available
|
|
19
|
+
* to AngularJS. That is migrated code, not code left to migrate.
|
|
20
|
+
*/
|
|
21
|
+
downgraded: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** A directive definition object using what `UpgradeComponent` rejects. */
|
|
24
|
+
export interface LegacyDirective {
|
|
25
|
+
line: number;
|
|
26
|
+
/** Which of `compile`, `replace`, `terminal` it sets. */
|
|
27
|
+
keys: string[];
|
|
28
|
+
}
|
|
29
|
+
/** Everything the AngularJS check needs from one JavaScript or TypeScript file. */
|
|
30
|
+
export interface AngularJsFileFacts {
|
|
31
|
+
/** Report path. */
|
|
32
|
+
path: string;
|
|
33
|
+
language: 'js' | 'ts';
|
|
34
|
+
isSpec: boolean;
|
|
35
|
+
/** Non-blank lines. */
|
|
36
|
+
linesOfCode: number;
|
|
37
|
+
/** Lines of `angular.module('x', [...])`, the form that defines a module (one argument only looks it up). */
|
|
38
|
+
moduleDefinitions: number[];
|
|
39
|
+
registrations: Registration[];
|
|
40
|
+
/** Lines mentioning `$scope`, as a parameter, a string in an injection array, or a reference. */
|
|
41
|
+
scopeLines: number[];
|
|
42
|
+
/** `$rootScope.$broadcast/$emit/$on` and `$scope.$broadcast/$emit`: events used as a message bus. */
|
|
43
|
+
scopeEventLines: number[];
|
|
44
|
+
/** `$watch`, `$watchCollection` and `$watchGroup` calls. */
|
|
45
|
+
watcherLines: number[];
|
|
46
|
+
/** Calls of an injected `$compile`: templates compiled at runtime. */
|
|
47
|
+
compileLines: number[];
|
|
48
|
+
legacyDirectives: LegacyDirective[];
|
|
49
|
+
/** `$routeProvider.when(…)` and `$stateProvider.state(…)`: routes to move to the Angular router. */
|
|
50
|
+
routeLines: number[];
|
|
51
|
+
/** `class X extends UpgradeComponent`: an AngularJS component wrapped for use in Angular. */
|
|
52
|
+
upgradedComponents: number;
|
|
53
|
+
/** Provider objects whose `deps` include `'$injector'`: AngularJS services made injectable in Angular. */
|
|
54
|
+
upgradedServices: number;
|
|
55
|
+
}
|
|
56
|
+
/** What `scanAngularJsFile` found: the facts, a vendored copy of AngularJS itself, or nothing worth keeping. */
|
|
57
|
+
export type AngularJsScan = {
|
|
58
|
+
facts: AngularJsFileFacts;
|
|
59
|
+
} | {
|
|
60
|
+
vendoredVersion: string;
|
|
61
|
+
} | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Reads one file for AngularJS code. Syntax-only, like `scanSourceFile`, and
|
|
64
|
+
* it runs on `.js` as well as `.ts` files, since most AngularJS code is
|
|
65
|
+
* plain JavaScript.
|
|
66
|
+
*
|
|
67
|
+
* Skips, by returning undefined: files that cannot contain AngularJS code
|
|
68
|
+
* (see `CANDIDATE`), minified files (very long lines), and files where
|
|
69
|
+
* nothing was found. A copy of `angular.js` itself returns its version
|
|
70
|
+
* instead, which is how an app that loads AngularJS from a checked-in file
|
|
71
|
+
* still gets a version in the report.
|
|
72
|
+
*/
|
|
73
|
+
export declare function scanAngularJsFile(root: string, absolutePath: string, text?: string): AngularJsScan;
|
|
74
|
+
/** AngularJS attributes in one HTML file. */
|
|
75
|
+
export interface AngularJsTemplateStats {
|
|
76
|
+
/** `ng-*="…"` and `data-ng-*="…"` attributes, which Angular templates never use. Bootstrap attributes such as `ng-app` are left out. */
|
|
77
|
+
attributes: number;
|
|
78
|
+
/** `ng-controller`: a controller bound in the template, which ngUpgrade cannot bridge. */
|
|
79
|
+
controllers: number;
|
|
80
|
+
/** `ng-include`: templates pulled in at runtime, with no Angular equivalent. */
|
|
81
|
+
includes: number;
|
|
82
|
+
/** `ng-app`: where AngularJS bootstraps. */
|
|
83
|
+
apps: number;
|
|
84
|
+
/** The AngularJS version in a CDN `<script>` URL, such as `…/angularjs/1.8.2/angular.min.js`. */
|
|
85
|
+
cdnVersion?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Counts AngularJS syntax in a template. Only attributes with a value are
|
|
89
|
+
* counted (`ng-repeat="…"`): `class="a ng-hide b"` would otherwise match, and
|
|
90
|
+
* Angular's own `<ng-container>`/`<ng-template>` are elements, not attributes.
|
|
91
|
+
* Commented-out markup is not counted either (see `withoutHtmlComments`).
|
|
92
|
+
*/
|
|
93
|
+
export declare function scanAngularJsTemplate(template: string): AngularJsTemplateStats;
|
|
94
|
+
/** `dependencies.angular` (or `devDependencies`) of `bower.json` at the root: how AngularJS apps installed packages before npm. */
|
|
95
|
+
export declare function readBowerAngular(root: string): {
|
|
96
|
+
version?: string;
|
|
97
|
+
exists: boolean;
|
|
98
|
+
};
|
|
99
|
+
/** Where the AngularJS version in a report was read from. */
|
|
100
|
+
export type AngularJsVersionSource = 'node_modules or lockfile' | 'package.json range' | 'bower.json' | 'script tag' | 'vendored copy';
|
|
101
|
+
/** Everything AngularJS in the repository, as `AnalysisContext.angularJs`. */
|
|
102
|
+
export interface AngularJsFacts {
|
|
103
|
+
/** Files with AngularJS code, test files included (checks filter them). */
|
|
104
|
+
files: AngularJsFileFacts[];
|
|
105
|
+
/** External templates with AngularJS syntax. */
|
|
106
|
+
templates: Array<{
|
|
107
|
+
path: string;
|
|
108
|
+
stats: AngularJsTemplateStats;
|
|
109
|
+
}>;
|
|
110
|
+
/** Undefined when AngularJS is neither a dependency nor loaded from a recognisable file or URL. */
|
|
111
|
+
version?: {
|
|
112
|
+
version: string;
|
|
113
|
+
source: AngularJsVersionSource;
|
|
114
|
+
};
|
|
115
|
+
/** A `bower.json` at the root. */
|
|
116
|
+
bower: boolean;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Assembles `AngularJsFacts` from the scanned files. The version comes from
|
|
120
|
+
* the first source that has one, most exact first: the installed or locked
|
|
121
|
+
* `angular` package, its `package.json` range, `bower.json`, a CDN script
|
|
122
|
+
* tag, a checked-in copy of `angular.js`.
|
|
123
|
+
*
|
|
124
|
+
* @param scans One result of `scanAngularJsFile` per JavaScript or
|
|
125
|
+
* candidate TypeScript file.
|
|
126
|
+
* @param templates Every external template; those with AngularJS syntax are kept.
|
|
127
|
+
* @param angular `versions.angular` and `dependencies.angular` of the workspace.
|
|
128
|
+
*/
|
|
129
|
+
export declare function assembleAngularJs(root: string, scans: AngularJsScan[], templates: Array<{
|
|
130
|
+
path: string;
|
|
131
|
+
inline: boolean;
|
|
132
|
+
angularJs?: AngularJsTemplateStats;
|
|
133
|
+
}>, angular: {
|
|
134
|
+
exact?: string;
|
|
135
|
+
declared?: string;
|
|
136
|
+
}): AngularJsFacts;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
import { isTestCode, toReportPath } from './files.js';
|
|
5
|
+
import { withoutHtmlComments } from './template-text.js';
|
|
6
|
+
const REGISTRATION_KINDS = new Set(['component', 'directive', 'controller', 'service', 'factory', 'provider', 'filter']);
|
|
7
|
+
/**
|
|
8
|
+
* Cheap test before a parse: files without any of these strings cannot hold
|
|
9
|
+
* AngularJS code, and a monorepo's Node backend can have thousands of them.
|
|
10
|
+
* Whitespace around the dots is allowed: the AngularJS tutorial itself writes
|
|
11
|
+
* `angular.` and `module('x').` at line ends.
|
|
12
|
+
*/
|
|
13
|
+
const CANDIDATE = /angular\s*\.\s*module|\$scope|\$rootScope|\$compile|\$routeProvider|\$stateProvider|UpgradeComponent|\$injector|\.\s*(controller|directive|component|service|factory|provider|filter)\s*\(\s*['"`]/;
|
|
14
|
+
/**
|
|
15
|
+
* The version in the license header AngularJS ships in every build
|
|
16
|
+
* (`@license AngularJS v1.5.8`). A file that carries it is a copy of the
|
|
17
|
+
* framework, not application code.
|
|
18
|
+
*/
|
|
19
|
+
const ANGULARJS_LICENSE = /@license AngularJS v(1\.\d+\.\d+)/;
|
|
20
|
+
/**
|
|
21
|
+
* Reads one file for AngularJS code. Syntax-only, like `scanSourceFile`, and
|
|
22
|
+
* it runs on `.js` as well as `.ts` files, since most AngularJS code is
|
|
23
|
+
* plain JavaScript.
|
|
24
|
+
*
|
|
25
|
+
* Skips, by returning undefined: files that cannot contain AngularJS code
|
|
26
|
+
* (see `CANDIDATE`), minified files (very long lines), and files where
|
|
27
|
+
* nothing was found. A copy of `angular.js` itself returns its version
|
|
28
|
+
* instead, which is how an app that loads AngularJS from a checked-in file
|
|
29
|
+
* still gets a version in the report.
|
|
30
|
+
*/
|
|
31
|
+
export function scanAngularJsFile(root, absolutePath, text = readFileSync(absolutePath, 'utf8')) {
|
|
32
|
+
const head = text.slice(0, 2000);
|
|
33
|
+
const vendored = ANGULARJS_LICENSE.exec(head);
|
|
34
|
+
if (vendored)
|
|
35
|
+
return { vendoredVersion: vendored[1] };
|
|
36
|
+
if (!CANDIDATE.test(text) || isMinified(text))
|
|
37
|
+
return undefined;
|
|
38
|
+
const language = absolutePath.endsWith('.ts') ? 'ts' : 'js';
|
|
39
|
+
const source = ts.createSourceFile(absolutePath, text, ts.ScriptTarget.Latest, true, language === 'ts' ? ts.ScriptKind.TS : ts.ScriptKind.JS);
|
|
40
|
+
const path = toReportPath(root, absolutePath);
|
|
41
|
+
const facts = {
|
|
42
|
+
path,
|
|
43
|
+
language,
|
|
44
|
+
isSpec: isTestCode(path),
|
|
45
|
+
linesOfCode: text.split('\n').filter((line) => line.trim() !== '').length,
|
|
46
|
+
moduleDefinitions: [],
|
|
47
|
+
registrations: [],
|
|
48
|
+
scopeLines: [],
|
|
49
|
+
scopeEventLines: [],
|
|
50
|
+
watcherLines: [],
|
|
51
|
+
compileLines: [],
|
|
52
|
+
legacyDirectives: [],
|
|
53
|
+
routeLines: [],
|
|
54
|
+
upgradedComponents: 0,
|
|
55
|
+
upgradedServices: 0,
|
|
56
|
+
};
|
|
57
|
+
const lineOf = (node) => source.getLineAndCharacterOfPosition(node.getStart(source)).line + 1;
|
|
58
|
+
const addLine = (lines, node) => {
|
|
59
|
+
const line = lineOf(node);
|
|
60
|
+
if (lines[lines.length - 1] !== line)
|
|
61
|
+
lines.push(line);
|
|
62
|
+
};
|
|
63
|
+
/** Variables this file assigned from `angular.module(…)`, so `homeModule.controller()` counts as rooted. */
|
|
64
|
+
const moduleVariables = new Set();
|
|
65
|
+
const collectModuleVariables = (node) => {
|
|
66
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && isModuleChain(node.initializer, moduleVariables))
|
|
67
|
+
moduleVariables.add(node.name.text);
|
|
68
|
+
ts.forEachChild(node, collectModuleVariables);
|
|
69
|
+
};
|
|
70
|
+
collectModuleVariables(source);
|
|
71
|
+
const visit = (node) => {
|
|
72
|
+
if (ts.isCallExpression(node)) {
|
|
73
|
+
const callee = node.expression;
|
|
74
|
+
if (isAngularModuleCall(node)) {
|
|
75
|
+
if (node.arguments.length >= 2)
|
|
76
|
+
facts.moduleDefinitions.push(lineOf(node));
|
|
77
|
+
}
|
|
78
|
+
else if (ts.isPropertyAccessExpression(callee)) {
|
|
79
|
+
const method = callee.name.text;
|
|
80
|
+
const [first, second] = node.arguments;
|
|
81
|
+
const name = first && (ts.isStringLiteral(first) || ts.isNoSubstitutionTemplateLiteral(first)) ? first.text : undefined;
|
|
82
|
+
if (REGISTRATION_KINDS.has(method) && name !== undefined && second !== undefined) {
|
|
83
|
+
facts.registrations.push({ kind: method, name, line: lineOf(node), rooted: isModuleChain(callee.expression, moduleVariables), downgraded: isDowngradeCall(second) });
|
|
84
|
+
}
|
|
85
|
+
else if (method === '$watch' || method === '$watchCollection' || method === '$watchGroup') {
|
|
86
|
+
facts.watcherLines.push(lineOf(node));
|
|
87
|
+
}
|
|
88
|
+
else if (isScopeEvent(callee)) {
|
|
89
|
+
facts.scopeEventLines.push(lineOf(node));
|
|
90
|
+
}
|
|
91
|
+
else if ((method === 'when' && chainRoot(callee) === '$routeProvider') || (method === 'state' && chainRoot(callee) === '$stateProvider')) {
|
|
92
|
+
facts.routeLines.push(lineOf(node));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (ts.isIdentifier(callee) && callee.text === '$compile') {
|
|
96
|
+
facts.compileLines.push(lineOf(node));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (ts.isIdentifier(node) && node.text === '$scope') {
|
|
100
|
+
addLine(facts.scopeLines, node);
|
|
101
|
+
}
|
|
102
|
+
else if (ts.isStringLiteral(node) && node.text === '$scope') {
|
|
103
|
+
addLine(facts.scopeLines, node);
|
|
104
|
+
}
|
|
105
|
+
else if (ts.isObjectLiteralExpression(node)) {
|
|
106
|
+
const legacy = legacyDirectiveKeys(node);
|
|
107
|
+
if (legacy.length > 0)
|
|
108
|
+
facts.legacyDirectives.push({ line: lineOf(node), keys: legacy });
|
|
109
|
+
if (isUpgradedServiceProvider(node))
|
|
110
|
+
facts.upgradedServices++;
|
|
111
|
+
}
|
|
112
|
+
else if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
|
|
113
|
+
const extendsClause = node.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword);
|
|
114
|
+
const base = extendsClause?.types[0]?.expression;
|
|
115
|
+
if (base && ts.isIdentifier(base) && base.text === 'UpgradeComponent')
|
|
116
|
+
facts.upgradedComponents++;
|
|
117
|
+
}
|
|
118
|
+
ts.forEachChild(node, visit);
|
|
119
|
+
};
|
|
120
|
+
visit(source);
|
|
121
|
+
const found = facts.moduleDefinitions.length +
|
|
122
|
+
facts.registrations.length +
|
|
123
|
+
facts.scopeLines.length +
|
|
124
|
+
facts.compileLines.length +
|
|
125
|
+
facts.routeLines.length +
|
|
126
|
+
facts.upgradedComponents +
|
|
127
|
+
facts.upgradedServices;
|
|
128
|
+
return found > 0 ? { facts } : undefined;
|
|
129
|
+
}
|
|
130
|
+
/** `angular.module(…)`, also on a namespace or default import named `angular`. */
|
|
131
|
+
function isAngularModuleCall(node) {
|
|
132
|
+
const callee = node.expression;
|
|
133
|
+
return ts.isPropertyAccessExpression(callee) && callee.name.text === 'module' && ts.isIdentifier(callee.expression) && callee.expression.text === 'angular';
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* True when `expression` is, or ends a chain that starts at,
|
|
137
|
+
* `angular.module(…)`: `angular.module('a').controller(…).service(…)` and
|
|
138
|
+
* `homeModule` after `let homeModule = angular.module('app.home', [])`.
|
|
139
|
+
*/
|
|
140
|
+
function isModuleChain(expression, moduleVariables) {
|
|
141
|
+
let current = expression;
|
|
142
|
+
for (;;) {
|
|
143
|
+
if (ts.isParenthesizedExpression(current))
|
|
144
|
+
current = current.expression;
|
|
145
|
+
else if (ts.isIdentifier(current))
|
|
146
|
+
return moduleVariables.has(current.text);
|
|
147
|
+
else if (ts.isCallExpression(current)) {
|
|
148
|
+
if (isAngularModuleCall(current))
|
|
149
|
+
return true;
|
|
150
|
+
if (!ts.isPropertyAccessExpression(current.expression))
|
|
151
|
+
return false;
|
|
152
|
+
current = current.expression.expression;
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** The identifier a call chain such as `$routeProvider.when(…).when(…)` starts at. */
|
|
159
|
+
function chainRoot(callee) {
|
|
160
|
+
let current = callee.expression;
|
|
161
|
+
while (ts.isCallExpression(current) && ts.isPropertyAccessExpression(current.expression))
|
|
162
|
+
current = current.expression.expression;
|
|
163
|
+
return ts.isIdentifier(current) ? current.text : undefined;
|
|
164
|
+
}
|
|
165
|
+
/** `downgradeInjectable(X)` or `downgradeComponent({…})`, by name: that is what the upgrade guide writes. */
|
|
166
|
+
function isDowngradeCall(expression) {
|
|
167
|
+
if (!ts.isCallExpression(expression))
|
|
168
|
+
return false;
|
|
169
|
+
const callee = expression.expression;
|
|
170
|
+
const name = ts.isIdentifier(callee) ? callee.text : ts.isPropertyAccessExpression(callee) ? callee.name.text : '';
|
|
171
|
+
return name === 'downgradeInjectable' || name === 'downgradeComponent';
|
|
172
|
+
}
|
|
173
|
+
/** `$rootScope.$broadcast/$emit/$on` or `$scope.$broadcast/$emit`. `$scope.$on` is left out: mostly `$destroy` cleanup, not a message bus. */
|
|
174
|
+
function isScopeEvent(callee) {
|
|
175
|
+
const receiver = callee.expression;
|
|
176
|
+
if (!ts.isIdentifier(receiver))
|
|
177
|
+
return false;
|
|
178
|
+
const method = callee.name.text;
|
|
179
|
+
if (receiver.text === '$rootScope')
|
|
180
|
+
return method === '$broadcast' || method === '$emit' || method === '$on';
|
|
181
|
+
return receiver.text === '$scope' && (method === '$broadcast' || method === '$emit');
|
|
182
|
+
}
|
|
183
|
+
/** Keys that only a directive definition object has, so `{ replace: true }` elsewhere is not mistaken for one. */
|
|
184
|
+
const DIRECTIVE_KEYS = new Set(['restrict', 'link', 'template', 'templateUrl', 'transclude', 'require', 'bindToController', 'controllerAs', 'priority', 'scope']);
|
|
185
|
+
/**
|
|
186
|
+
* The keys of a directive definition object that `UpgradeComponent` refuses
|
|
187
|
+
* (it throws "Upgraded directive … contains unsupported feature"): `compile`,
|
|
188
|
+
* `replace: true` and `terminal: true`. Empty for any other object.
|
|
189
|
+
*/
|
|
190
|
+
function legacyDirectiveKeys(node) {
|
|
191
|
+
const keys = new Map();
|
|
192
|
+
for (const property of node.properties) {
|
|
193
|
+
const name = property.name && (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) ? property.name.text : undefined;
|
|
194
|
+
if (name)
|
|
195
|
+
keys.set(name, property);
|
|
196
|
+
}
|
|
197
|
+
if (![...keys.keys()].some((key) => DIRECTIVE_KEYS.has(key)))
|
|
198
|
+
return [];
|
|
199
|
+
const isTrue = (key) => {
|
|
200
|
+
const property = keys.get(key);
|
|
201
|
+
return property !== undefined && ts.isPropertyAssignment(property) && property.initializer.kind === ts.SyntaxKind.TrueKeyword;
|
|
202
|
+
};
|
|
203
|
+
const legacy = [];
|
|
204
|
+
if (keys.has('compile'))
|
|
205
|
+
legacy.push('compile');
|
|
206
|
+
if (isTrue('replace'))
|
|
207
|
+
legacy.push('replace');
|
|
208
|
+
if (isTrue('terminal'))
|
|
209
|
+
legacy.push('terminal');
|
|
210
|
+
return legacy;
|
|
211
|
+
}
|
|
212
|
+
/** `{ provide: X, useFactory: (i) => i.get('heroes'), deps: ['$injector'] }`. */
|
|
213
|
+
function isUpgradedServiceProvider(node) {
|
|
214
|
+
return node.properties.some((property) => ts.isPropertyAssignment(property) &&
|
|
215
|
+
ts.isIdentifier(property.name) &&
|
|
216
|
+
property.name.text === 'deps' &&
|
|
217
|
+
ts.isArrayLiteralExpression(property.initializer) &&
|
|
218
|
+
property.initializer.elements.some((element) => ts.isStringLiteral(element) && element.text === '$injector'));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* True for a minified file: some line longer than 1 000 characters within
|
|
222
|
+
* the first 20 lines. Hand-written code never has one; a bundle or a
|
|
223
|
+
* `.min.js` always does.
|
|
224
|
+
*/
|
|
225
|
+
function isMinified(text) {
|
|
226
|
+
return text
|
|
227
|
+
.split('\n', 20)
|
|
228
|
+
.some((line) => line.length > 1000);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Counts AngularJS syntax in a template. Only attributes with a value are
|
|
232
|
+
* counted (`ng-repeat="…"`): `class="a ng-hide b"` would otherwise match, and
|
|
233
|
+
* Angular's own `<ng-container>`/`<ng-template>` are elements, not attributes.
|
|
234
|
+
* Commented-out markup is not counted either (see `withoutHtmlComments`).
|
|
235
|
+
*/
|
|
236
|
+
export function scanAngularJsTemplate(template) {
|
|
237
|
+
const text = withoutHtmlComments(template);
|
|
238
|
+
const count = (pattern) => (text.match(pattern) ?? []).length;
|
|
239
|
+
const cdn = /<script[^>]+src=["'][^"']*angular(?:js|\.js)?[/@](1\.\d+\.\d+)[^"']*["']/i.exec(text);
|
|
240
|
+
return {
|
|
241
|
+
// Bootstrap attributes (`ng-app`, `ng-strict-di`, `ng-csp`, `ng-jq`) mark the host page, not a template to rewrite.
|
|
242
|
+
// `ng-reflect-*` and `ng-version` are what Angular itself writes into the DOM in dev mode; they end up in
|
|
243
|
+
// templates pasted from the browser's dev tools (an Ionic app's notifications page had a dozen).
|
|
244
|
+
attributes: count(/\s(?:data-)?ng-(?!(?:app|strict-di|csp|jq|version|reflect-[a-z-]+)\b)[a-z][a-z-]*\s*=\s*["']/g),
|
|
245
|
+
controllers: count(/\s(?:data-)?ng-controller\s*=\s*["']/g),
|
|
246
|
+
includes: count(/\s(?:data-)?ng-include\s*=\s*["']|<ng-include[\s>]/g),
|
|
247
|
+
apps: count(/\s(?:data-)?ng-app(?:\s*=|[\s>])/g),
|
|
248
|
+
...(cdn ? { cdnVersion: cdn[1] } : {}),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** `dependencies.angular` (or `devDependencies`) of `bower.json` at the root: how AngularJS apps installed packages before npm. */
|
|
252
|
+
export function readBowerAngular(root) {
|
|
253
|
+
try {
|
|
254
|
+
const bower = JSON.parse(readFileSync(join(root, 'bower.json'), 'utf8'));
|
|
255
|
+
const version = bower.dependencies?.['angular'] ?? bower.devDependencies?.['angular'];
|
|
256
|
+
return { exists: true, ...(version ? { version } : {}) };
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return { exists: false };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Assembles `AngularJsFacts` from the scanned files. The version comes from
|
|
264
|
+
* the first source that has one, most exact first: the installed or locked
|
|
265
|
+
* `angular` package, its `package.json` range, `bower.json`, a CDN script
|
|
266
|
+
* tag, a checked-in copy of `angular.js`.
|
|
267
|
+
*
|
|
268
|
+
* @param scans One result of `scanAngularJsFile` per JavaScript or
|
|
269
|
+
* candidate TypeScript file.
|
|
270
|
+
* @param templates Every external template; those with AngularJS syntax are kept.
|
|
271
|
+
* @param angular `versions.angular` and `dependencies.angular` of the workspace.
|
|
272
|
+
*/
|
|
273
|
+
export function assembleAngularJs(root, scans, templates, angular) {
|
|
274
|
+
const files = scans.flatMap((scan) => (scan && 'facts' in scan ? [scan.facts] : []));
|
|
275
|
+
const vendored = scans.flatMap((scan) => (scan && 'vendoredVersion' in scan ? [scan.vendoredVersion] : []))[0];
|
|
276
|
+
const withSyntax = templates.flatMap((template) => (!template.inline && template.angularJs ? [{ path: template.path, stats: template.angularJs }] : []));
|
|
277
|
+
const cdn = withSyntax.find((template) => template.stats.cdnVersion)?.stats.cdnVersion;
|
|
278
|
+
const bower = readBowerAngular(root);
|
|
279
|
+
const version = angular.exact
|
|
280
|
+
? { version: angular.exact, source: 'node_modules or lockfile' }
|
|
281
|
+
: angular.declared
|
|
282
|
+
? { version: angular.declared.replace(/^[\s^~>=<]+/, ''), source: 'package.json range' }
|
|
283
|
+
: bower.version
|
|
284
|
+
? { version: bower.version, source: 'bower.json' }
|
|
285
|
+
: cdn
|
|
286
|
+
? { version: cdn, source: 'script tag' }
|
|
287
|
+
: vendored
|
|
288
|
+
? { version: vendored, source: 'vendored copy' }
|
|
289
|
+
: undefined;
|
|
290
|
+
return { files, templates: withSyntax, ...(version ? { version } : {}), bower: bower.exists };
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=angularjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angularjs.js","sourceRoot":"","sources":["../src/angularjs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKzD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAmB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AA0D3I;;;;;GAKG;AACH,MAAM,SAAS,GAAG,oMAAoM,CAAC;AAEvN;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,mCAAmC,CAAC;AAK9D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,YAAoB,EAAE,IAAI,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC;IAC7G,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,QAAQ;QAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,CAAC;IACvD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhE,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,MAAM,MAAM,GAAG,EAAE,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9I,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAuB;QAChC,IAAI;QACJ,QAAQ;QACR,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;QACxB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM;QACzE,iBAAiB,EAAE,EAAE;QACrB,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,EAAE;QACd,eAAe,EAAE,EAAE;QACnB,YAAY,EAAE,EAAE;QAChB,YAAY,EAAE,EAAE;QAChB,gBAAgB,EAAE,EAAE;QACpB,UAAU,EAAE,EAAE;QACd,kBAAkB,EAAE,CAAC;QACrB,gBAAgB,EAAE,CAAC;KACpB,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,IAAa,EAAU,EAAE,CAAC,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAC/G,MAAM,OAAO,GAAG,CAAC,KAAe,EAAE,IAAa,EAAQ,EAAE;QACvD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC,CAAC;IAEF,4GAA4G;IAC5G,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,MAAM,sBAAsB,GAAG,CAAC,IAAa,EAAQ,EAAE;QACrD,IAAI,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC;YAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9K,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;IAChD,CAAC,CAAC;IACF,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/B,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;YAC/B,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC;oBAAE,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7E,CAAC;iBAAM,IAAI,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBAChC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;gBACvC,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,+BAA+B,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;gBACxH,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAA0B,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACrG,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAA0B,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,EAAE,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC3L,CAAC;qBAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,kBAAkB,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;oBAC5F,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxC,CAAC;qBAAM,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;oBAChC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,gBAAgB,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,gBAAgB,CAAC,EAAE,CAAC;oBAC3I,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;iBAAM,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACjE,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9D,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACzF,IAAI,yBAAyB,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAChE,CAAC;aAAM,IAAI,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YACrE,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC5G,MAAM,IAAI,GAAG,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;YACjD,IAAI,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB;gBAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC;QACpG,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,CAAC,CAAC;IAEd,MAAM,KAAK,GACT,KAAK,CAAC,iBAAiB,CAAC,MAAM;QAC9B,KAAK,CAAC,aAAa,CAAC,MAAM;QAC1B,KAAK,CAAC,UAAU,CAAC,MAAM;QACvB,KAAK,CAAC,YAAY,CAAC,MAAM;QACzB,KAAK,CAAC,UAAU,CAAC,MAAM;QACvB,KAAK,CAAC,kBAAkB;QACxB,KAAK,CAAC,gBAAgB,CAAC;IACzB,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED,kFAAkF;AAClF,SAAS,mBAAmB,CAAC,IAAuB;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IAC/B,OAAO,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS,CAAC;AAC9J,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,UAAyB,EAAE,eAA4B;IAC5E,IAAI,OAAO,GAAkB,UAAU,CAAC;IACxC,SAAS,CAAC;QACR,IAAI,EAAE,CAAC,yBAAyB,CAAC,OAAO,CAAC;YAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;aACnE,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;YAAE,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;aACvE,IAAI,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,IAAI,mBAAmB,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC9C,IAAI,CAAC,EAAE,CAAC,0BAA0B,CAAC,OAAO,CAAC,UAAU,CAAC;gBAAE,OAAO,KAAK,CAAC;YACrE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;QAC1C,CAAC;;YAAM,OAAO,KAAK,CAAC;IACtB,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,SAAS,SAAS,CAAC,MAAmC;IACpD,IAAI,OAAO,GAAkB,MAAM,CAAC,UAAU,CAAC;IAC/C,OAAO,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,0BAA0B,CAAC,OAAO,CAAC,UAAU,CAAC;QAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;IAClI,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC;AAED,6GAA6G;AAC7G,SAAS,eAAe,CAAC,UAAyB;IAChD,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnH,OAAO,IAAI,KAAK,qBAAqB,IAAI,IAAI,KAAK,oBAAoB,CAAC;AACzE,CAAC;AAED,8IAA8I;AAC9I,SAAS,YAAY,CAAC,MAAmC;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IAChC,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,KAAK,CAAC;IAC7G,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,OAAO,CAAC,CAAC;AACvF,CAAC;AAED,kHAAkH;AAClH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAElK;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,IAAgC;IAC3D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAmB,CAAC;IACxC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACrI,IAAI,IAAI;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IACxE,MAAM,MAAM,GAAG,CAAC,GAAW,EAAW,EAAE;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,QAAQ,KAAK,SAAS,IAAI,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;IAChI,CAAC,CAAC;IACF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,SAAS,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,UAAU,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,SAAS,yBAAyB,CAAC,IAAgC;IACjE,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CACzB,CAAC,QAAQ,EAAE,EAAE,CACX,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;QACjC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;QAC7B,EAAE,CAAC,wBAAwB,CAAC,QAAQ,CAAC,WAAW,CAAC;QACjD,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAC/G,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;SACf,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AACxC,CAAC;AAgBD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IAC9E,MAAM,GAAG,GAAG,2EAA2E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnG,OAAO;QACL,oHAAoH;QACpH,0GAA0G;QAC1G,iGAAiG;QACjG,UAAU,EAAE,KAAK,CAAC,+FAA+F,CAAC;QAClH,WAAW,EAAE,KAAK,CAAC,uCAAuC,CAAC;QAC3D,QAAQ,EAAE,KAAK,CAAC,qDAAqD,CAAC;QACtE,IAAI,EAAE,KAAK,CAAC,mCAAmC,CAAC;QAChD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,mIAAmI;AACnI,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAwF,CAAC;QAChK,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC,CAAC;QACtF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAiBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,KAAsB,EACtB,SAAuF,EACvF,OAA8C;IAE9C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,iBAAiB,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/G,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzJ,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC;IACvF,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,OAAO,GAA8B,OAAO,CAAC,KAAK;QACtD,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,0BAA0B,EAAE;QAChE,CAAC,CAAC,OAAO,CAAC,QAAQ;YAChB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE;YACxF,CAAC,CAAC,KAAK,CAAC,OAAO;gBACb,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE;gBAClD,CAAC,CAAC,GAAG;oBACH,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE;oBACxC,CAAC,CAAC,QAAQ;wBACR,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE;wBAChD,CAAC,CAAC,SAAS,CAAC;IACtB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AAChG,CAAC"}
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AngularJsScan } from './angularjs.js';
|
|
1
2
|
import type { PackageCompatibility } from './compatibility.js';
|
|
2
3
|
import type { DeprecationIndex } from './deprecations.js';
|
|
3
4
|
import type { SourceFileFacts, TemplateFact } from './scan.js';
|
|
@@ -14,9 +15,10 @@ import type { SourceFileFacts, TemplateFact } from './scan.js';
|
|
|
14
15
|
* be slow and impolite.
|
|
15
16
|
*/
|
|
16
17
|
export interface AnalysisCache {
|
|
18
|
+
/** Keyed by absolute path; AngularJS scans under `angularjs:` plus the path, since a `.ts` file is scanned both ways. */
|
|
17
19
|
files: Map<string, {
|
|
18
20
|
stamp: string;
|
|
19
|
-
facts:
|
|
21
|
+
facts: CachedFacts;
|
|
20
22
|
}>;
|
|
21
23
|
dependencies?: {
|
|
22
24
|
stamp: string;
|
|
@@ -29,6 +31,10 @@ export interface AnalysisCache {
|
|
|
29
31
|
};
|
|
30
32
|
};
|
|
31
33
|
}
|
|
34
|
+
/** What one file's scan produces, by kind of scan. */
|
|
35
|
+
export type CachedFacts = SourceFileFacts | TemplateFact | {
|
|
36
|
+
angularJs: AngularJsScan;
|
|
37
|
+
};
|
|
32
38
|
/** An empty cache. */
|
|
33
39
|
export declare function createAnalysisCache(): AnalysisCache;
|
|
34
40
|
/** `mtime:size` of a file, or an empty string when it cannot be read. */
|
|
@@ -39,4 +45,4 @@ export declare function dependencyStamp(root: string): string;
|
|
|
39
45
|
* The cached value for `path` when its stamp still matches, else `compute()`
|
|
40
46
|
* stored under the new stamp. Without a cache it just computes.
|
|
41
47
|
*/
|
|
42
|
-
export declare function cachedFacts<T extends
|
|
48
|
+
export declare function cachedFacts<T extends CachedFacts>(cache: AnalysisCache | undefined, path: string, compute: () => T, key?: string): T;
|
package/dist/cache.js
CHANGED
|
@@ -22,15 +22,15 @@ export function dependencyStamp(root) {
|
|
|
22
22
|
* The cached value for `path` when its stamp still matches, else `compute()`
|
|
23
23
|
* stored under the new stamp. Without a cache it just computes.
|
|
24
24
|
*/
|
|
25
|
-
export function cachedFacts(cache, path, compute) {
|
|
25
|
+
export function cachedFacts(cache, path, compute, key = path) {
|
|
26
26
|
if (!cache)
|
|
27
27
|
return compute();
|
|
28
28
|
const stamp = fileStamp(path);
|
|
29
|
-
const hit = cache.files.get(
|
|
29
|
+
const hit = cache.files.get(key);
|
|
30
30
|
if (hit && hit.stamp === stamp)
|
|
31
31
|
return hit.facts;
|
|
32
32
|
const facts = compute();
|
|
33
|
-
cache.files.set(
|
|
33
|
+
cache.files.set(key, { stamp, facts });
|
|
34
34
|
return facts;
|
|
35
35
|
}
|
|
36
36
|
//# sourceMappingURL=cache.js.map
|
package/dist/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAiCjC,sBAAsB;AACtB,MAAM,UAAU,mBAAmB;IACjC,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;AAC9B,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,CAAC,cAAc,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,iCAAiC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtK,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAwB,KAAgC,EAAE,IAAY,EAAE,OAAgB,EAAE,GAAG,GAAG,IAAI;IAC7H,IAAI,CAAC,KAAK;QAAE,OAAO,OAAO,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK;QAAE,OAAO,GAAG,CAAC,KAAU,CAAC;IACtD,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC;IACxB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC;AACf,CAAC"}
|