checkly 8.22.0 → 8.23.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.
- package/dist/ai-context/skills-command/references/configure-playwright-checks.md +24 -19
- package/dist/commands/debug/parse-project.js +3 -0
- package/dist/commands/debug/parse-project.js.map +1 -1
- package/dist/commands/deploy.js +3 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/pw-test.js +3 -0
- package/dist/commands/pw-test.js.map +1 -1
- package/dist/commands/test.js +3 -0
- package/dist/commands/test.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js.map +1 -1
- package/dist/constructs/playwright-check-bundle.d.ts +5 -5
- package/dist/constructs/playwright-check-bundle.js.map +1 -1
- package/dist/constructs/project.js +5 -2
- package/dist/constructs/project.js.map +1 -1
- package/dist/constructs/session.d.ts +2 -1
- package/dist/constructs/session.js +2 -1
- package/dist/constructs/session.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/services/check-parser/bundler.d.ts +79 -8
- package/dist/services/check-parser/bundler.js +567 -9
- package/dist/services/check-parser/bundler.js.map +1 -1
- package/dist/services/check-parser/cache-hash.d.ts +141 -17
- package/dist/services/check-parser/cache-hash.js +78 -12
- package/dist/services/check-parser/cache-hash.js.map +1 -1
- package/dist/services/check-parser/faux-package.d.ts +5 -0
- package/dist/services/check-parser/faux-package.js +9 -1
- package/dist/services/check-parser/faux-package.js.map +1 -1
- package/dist/services/check-parser/lockfile-pruner.d.ts +104 -0
- package/dist/services/check-parser/lockfile-pruner.js +1107 -0
- package/dist/services/check-parser/lockfile-pruner.js.map +1 -0
- package/dist/services/check-parser/package-files/package-manager.d.ts +34 -0
- package/dist/services/check-parser/package-files/package-manager.js +131 -3
- package/dist/services/check-parser/package-files/package-manager.js.map +1 -1
- package/dist/services/check-parser/package-files/pnpmfile.d.ts +40 -0
- package/dist/services/check-parser/package-files/pnpmfile.js +322 -0
- package/dist/services/check-parser/package-files/pnpmfile.js.map +1 -0
- package/dist/services/check-parser/package-files/resolver.d.ts +6 -1
- package/dist/services/check-parser/package-files/resolver.js +34 -0
- package/dist/services/check-parser/package-files/resolver.js.map +1 -1
- package/dist/services/check-parser/package-files/workspace.d.ts +16 -1
- package/dist/services/check-parser/package-files/workspace.js +17 -2
- package/dist/services/check-parser/package-files/workspace.js.map +1 -1
- package/dist/services/check-parser/package-prune.d.ts +68 -0
- package/dist/services/check-parser/package-prune.js +274 -0
- package/dist/services/check-parser/package-prune.js.map +1 -0
- package/dist/services/check-parser/parser.js +9 -0
- package/dist/services/check-parser/parser.js.map +1 -1
- package/dist/services/check-parser/patched-dependencies.d.ts +133 -0
- package/dist/services/check-parser/patched-dependencies.js +428 -0
- package/dist/services/check-parser/patched-dependencies.js.map +1 -0
- package/dist/services/checkly-config-loader.d.ts +164 -10
- package/dist/services/checkly-config-loader.js +39 -0
- package/dist/services/checkly-config-loader.js.map +1 -1
- package/dist/services/embedded-packages/cache.d.ts +8 -4
- package/dist/services/embedded-packages/cache.js +27 -6
- package/dist/services/embedded-packages/cache.js.map +1 -1
- package/dist/services/embedded-packages/diagnostics.d.ts +129 -0
- package/dist/services/embedded-packages/diagnostics.js +212 -0
- package/dist/services/embedded-packages/diagnostics.js.map +1 -0
- package/dist/services/embedded-packages/lockfile-filter.d.ts +20 -0
- package/dist/services/embedded-packages/lockfile-filter.js +40 -0
- package/dist/services/embedded-packages/lockfile-filter.js.map +1 -0
- package/dist/services/embedded-packages/lockfile-packages.d.ts +31 -2
- package/dist/services/embedded-packages/lockfile-packages.js +234 -30
- package/dist/services/embedded-packages/lockfile-packages.js.map +1 -1
- package/dist/services/embedded-packages/materializer.d.ts +19 -5
- package/dist/services/embedded-packages/materializer.js +445 -91
- package/dist/services/embedded-packages/materializer.js.map +1 -1
- package/dist/services/embedded-packages/npmrc.d.ts +163 -21
- package/dist/services/embedded-packages/npmrc.js +440 -75
- package/dist/services/embedded-packages/npmrc.js.map +1 -1
- package/dist/services/embedded-packages/spec.d.ts +89 -17
- package/dist/services/embedded-packages/spec.js +199 -30
- package/dist/services/embedded-packages/spec.js.map +1 -1
- package/dist/services/embedded-packages/url.d.ts +39 -0
- package/dist/services/embedded-packages/url.js +60 -0
- package/dist/services/embedded-packages/url.js.map +1 -0
- package/dist/services/playwright-project-bundler.js +27 -23
- package/dist/services/playwright-project-bundler.js.map +1 -1
- package/dist/services/runner/registries.d.ts +144 -0
- package/dist/services/runner/registries.js +232 -0
- package/dist/services/runner/registries.js.map +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +5 -5
|
@@ -3,7 +3,9 @@ import fs from 'node:fs/promises';
|
|
|
3
3
|
import { findPlaywrightConfigPath, getDefaultChecklyConfig, writeChecklyConfigFile } from './util.js';
|
|
4
4
|
import { Session } from '../constructs/index.js';
|
|
5
5
|
import { normalizeDependencyCacheVersion } from './check-parser/cache-hash.js';
|
|
6
|
+
import { normalizePackagePrune } from './check-parser/package-prune.js';
|
|
6
7
|
import { parseEmbeddedPackageSpec } from './embedded-packages/spec.js';
|
|
8
|
+
import { validateRegistries } from './runner/registries.js';
|
|
7
9
|
function isString(obj) {
|
|
8
10
|
return (Object.prototype.toString.call(obj) === '[object String]');
|
|
9
11
|
}
|
|
@@ -84,6 +86,7 @@ export async function loadChecklyConfig(dir, filenames = defaultFilenames, write
|
|
|
84
86
|
validateConfigFields(config, ['logicalId', 'projectName']);
|
|
85
87
|
validateDependencyCacheVersion(config);
|
|
86
88
|
validateBundle(config);
|
|
89
|
+
validateRunner(config);
|
|
87
90
|
const constructs = Session.checklyConfigFileConstructs;
|
|
88
91
|
Session.checklyConfigFileConstructs = [];
|
|
89
92
|
if (config.cli?.loader) {
|
|
@@ -141,6 +144,12 @@ function validateBundle(config) {
|
|
|
141
144
|
if (packages === null || typeof packages !== 'object' || Array.isArray(packages)) {
|
|
142
145
|
throw new Error(`Config field 'bundle.packages' must be an object if set`);
|
|
143
146
|
}
|
|
147
|
+
try {
|
|
148
|
+
normalizePackagePrune(packages.prune);
|
|
149
|
+
}
|
|
150
|
+
catch (cause) {
|
|
151
|
+
throw new Error(`Config field 'bundle.packages.prune' is invalid: ${cause.message}`, { cause });
|
|
152
|
+
}
|
|
144
153
|
const embeddedPackages = packages.embed;
|
|
145
154
|
if (embeddedPackages === undefined) {
|
|
146
155
|
return;
|
|
@@ -157,4 +166,34 @@ function validateBundle(config) {
|
|
|
157
166
|
}
|
|
158
167
|
}
|
|
159
168
|
}
|
|
169
|
+
function validateRunner(config) {
|
|
170
|
+
const { runner } = config;
|
|
171
|
+
if (runner === undefined) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// Same rationale as `validateBundle`: plain-JS configs bypass the
|
|
175
|
+
// TypeScript type, and a misshapen `runner` block would otherwise read as
|
|
176
|
+
// `registries: undefined` and silently disable routing, surfacing only as
|
|
177
|
+
// an install failure on the runner.
|
|
178
|
+
if (runner === null || typeof runner !== 'object' || Array.isArray(runner)) {
|
|
179
|
+
throw new Error(`Config field 'runner' must be an object if set`);
|
|
180
|
+
}
|
|
181
|
+
// A misspelled key (`registires`) would silently disable routing the same
|
|
182
|
+
// way a misshapen block would.
|
|
183
|
+
for (const key of Object.keys(runner)) {
|
|
184
|
+
if (key !== 'registries') {
|
|
185
|
+
throw new Error(`Config field 'runner' contains unknown field '${key}' (expected only: 'registries')`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const { registries } = runner;
|
|
189
|
+
if (registries === undefined) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
validateRegistries(registries);
|
|
194
|
+
}
|
|
195
|
+
catch (cause) {
|
|
196
|
+
throw new Error(`Config field 'runner.registries' is invalid: ${cause.message}`, { cause });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
160
199
|
//# sourceMappingURL=checkly-config-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkly-config-loader.js","sourceRoot":"","sources":["../../src/services/checkly-config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAGrG,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAMhD,OAAO,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAA;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"checkly-config-loader.js","sourceRoot":"","sources":["../../src/services/checkly-config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,8 @@ export declare function resolveCacheDirs(env?: NodeJS.ProcessEnv, projectRoot?:
|
|
|
18
18
|
* Reads consult every root and verify the content, so a corrupt entry
|
|
19
19
|
* degrades to a cache miss rather than a user-facing error. Writes go to
|
|
20
20
|
* the first root that accepts them, so an unwritable project tree falls
|
|
21
|
-
* back to the per-user cache instead of failing
|
|
21
|
+
* back to the per-user cache instead of failing — unless the unwritable
|
|
22
|
+
* root already holds a verifying entry, which satisfies the write as-is.
|
|
22
23
|
*/
|
|
23
24
|
export declare class TarballCache {
|
|
24
25
|
#private;
|
|
@@ -32,9 +33,12 @@ export declare class TarballCache {
|
|
|
32
33
|
/**
|
|
33
34
|
* Stores verified tarball content in the first writable root and returns
|
|
34
35
|
* its path. The write is atomic (temp file + rename), so concurrent
|
|
35
|
-
* processes sharing the cache never observe a torn file
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* processes sharing the cache never observe a torn file — and because
|
|
37
|
+
* the store is content-addressed, losing a write race is itself a
|
|
38
|
+
* success: a write that fails while the destination already holds
|
|
39
|
+
* content matching the integrity returns that entry instead of erroring.
|
|
40
|
+
* The caller is responsible for verifying the content against the
|
|
41
|
+
* lockfile integrity beforehand.
|
|
38
42
|
*/
|
|
39
43
|
put(integrity: string, content: Buffer): Promise<string>;
|
|
40
44
|
}
|
|
@@ -56,7 +56,8 @@ export function resolveCacheDirs(env = process.env, projectRoot, platform = proc
|
|
|
56
56
|
* Reads consult every root and verify the content, so a corrupt entry
|
|
57
57
|
* degrades to a cache miss rather than a user-facing error. Writes go to
|
|
58
58
|
* the first root that accepts them, so an unwritable project tree falls
|
|
59
|
-
* back to the per-user cache instead of failing
|
|
59
|
+
* back to the per-user cache instead of failing — unless the unwritable
|
|
60
|
+
* root already holds a verifying entry, which satisfies the write as-is.
|
|
60
61
|
*/
|
|
61
62
|
export class TarballCache {
|
|
62
63
|
#rootDirs;
|
|
@@ -100,9 +101,12 @@ export class TarballCache {
|
|
|
100
101
|
/**
|
|
101
102
|
* Stores verified tarball content in the first writable root and returns
|
|
102
103
|
* its path. The write is atomic (temp file + rename), so concurrent
|
|
103
|
-
* processes sharing the cache never observe a torn file
|
|
104
|
-
*
|
|
105
|
-
*
|
|
104
|
+
* processes sharing the cache never observe a torn file — and because
|
|
105
|
+
* the store is content-addressed, losing a write race is itself a
|
|
106
|
+
* success: a write that fails while the destination already holds
|
|
107
|
+
* content matching the integrity returns that entry instead of erroring.
|
|
108
|
+
* The caller is responsible for verifying the content against the
|
|
109
|
+
* lockfile integrity beforehand.
|
|
106
110
|
*/
|
|
107
111
|
async put(integrity, content) {
|
|
108
112
|
const hash = strongestIntegrityHash(integrity);
|
|
@@ -123,7 +127,23 @@ export class TarballCache {
|
|
|
123
127
|
return filePath;
|
|
124
128
|
}
|
|
125
129
|
catch (err) {
|
|
126
|
-
|
|
130
|
+
// Concurrent writers race onto the same content-addressed path —
|
|
131
|
+
// two same-integrity puts in this process, or another process
|
|
132
|
+
// sharing the cache. POSIX rename silently replaces, but on
|
|
133
|
+
// Windows the losing rename fails with EPERM while the winner
|
|
134
|
+
// still holds the destination open. Whatever failed, a
|
|
135
|
+
// destination that verifies means the content is cached, which is
|
|
136
|
+
// all a put promises. The recovery read is deliberately
|
|
137
|
+
// single-shot and best-effort: retrying would add fixed latency to
|
|
138
|
+
// every genuinely unwritable root (the common non-race case), so a
|
|
139
|
+
// read that itself hits a transient lock falls through to the
|
|
140
|
+
// normal failure path instead.
|
|
141
|
+
const existing = await fs.readFile(filePath).catch(() => undefined);
|
|
142
|
+
if (existing !== undefined && verifyIntegrity(existing, integrity)) {
|
|
143
|
+
debug('cache write under %s failed (%s), but the destination already verifies', rootDir, err.message);
|
|
144
|
+
return filePath;
|
|
145
|
+
}
|
|
146
|
+
debug('cache write under %s failed: %s', rootDir, err.message);
|
|
127
147
|
lastError = err;
|
|
128
148
|
}
|
|
129
149
|
finally {
|
|
@@ -131,7 +151,8 @@ export class TarballCache {
|
|
|
131
151
|
}
|
|
132
152
|
}
|
|
133
153
|
throw new Error(`Unable to write the embedded-packages cache`
|
|
134
|
-
+ ` (tried ${this.#rootDirs.map(dir => `'${dir}'`).join(', ')})
|
|
154
|
+
+ ` (tried ${this.#rootDirs.map(dir => `'${dir}'`).join(', ')}):`
|
|
155
|
+
+ ` ${lastError?.message ?? 'unknown error'}.`
|
|
135
156
|
+ ` Set CHECKLY_CACHE_DIR to a writable directory to override the cache location.`, { cause: lastError });
|
|
136
157
|
}
|
|
137
158
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/services/embedded-packages/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAiB,kBAAkB,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE3G,MAAM,KAAK,GAAG,KAAK,CAAC,wCAAwC,CAAC,CAAA;AAE7D,SAAS,gBAAgB,CACvB,GAAsB,EACtB,QAAyB,EACzB,OAAe;IAEf,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;QAC3D,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,KAAK,SAAS,IAAI,GAAG,CAAC,YAAY,KAAK,EAAE;gBAC5E,CAAC,CAAC,GAAG,CAAC,YAAY;gBAClB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;YAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QACpD,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,YAAY,GAAG,GAAG,CAAC,cAAc,CAAA;YACvC,MAAM,SAAS,GAAG,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,EAAE;gBACjE,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YAChC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACxC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAyB,OAAO,CAAC,GAAG,EACpC,WAAoB,EACpB,WAA4B,OAAO,CAAC,QAAQ,EAC5C,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE;IAEtB,MAAM,QAAQ,GAAG,GAAG,CAAC,iBAAiB,CAAA;IACtC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAA;IACf,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;IACnD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;AAC3B,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/services/embedded-packages/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { LoadedNpmrcConfig } from './npmrc.js';
|
|
2
|
+
/**
|
|
3
|
+
* Joins up to 8 items, appending `<overflow>N more` for the rest — the
|
|
4
|
+
* uniform truncation for user-facing lists of packages, versions and
|
|
5
|
+
* reasons.
|
|
6
|
+
*/
|
|
7
|
+
export declare function capList(items: string[], separator: string, overflow: string): string;
|
|
8
|
+
/** Quotes and joins a list of names for a message. */
|
|
9
|
+
export declare function quotedList(names: string[]): string;
|
|
10
|
+
/** Stand-in for a URL that cannot be shown without risking a credential. */
|
|
11
|
+
export declare const UNPRINTABLE_URL = "(withheld: unparseable and may contain credentials)";
|
|
12
|
+
/**
|
|
13
|
+
* Rebuilds a URL from the parts that cannot carry a credential, so it can
|
|
14
|
+
* safely appear in error messages and logs.
|
|
15
|
+
*
|
|
16
|
+
* Only scheme and host survive. Userinfo, path, query and fragment are
|
|
17
|
+
* dropped by construction rather than stripped: a registry URL may embed a
|
|
18
|
+
* token in its userinfo, a pre-signed CDN URL puts its signature in the
|
|
19
|
+
* query, and some registries take a token as a PATH segment
|
|
20
|
+
* (`https://host/<token>/npm/`). The path is the component least worth
|
|
21
|
+
* keeping anyway — every message that shows a URL already names the
|
|
22
|
+
* package and version separately, which is what the path encodes.
|
|
23
|
+
*
|
|
24
|
+
* A string that does not parse, parses without a host, or names a scheme
|
|
25
|
+
* nothing here fetches over yields the placeholder instead — deliberately
|
|
26
|
+
* the same rule as what may be requested, so a URL is echoable exactly when
|
|
27
|
+
* it was fetchable. Earlier revisions tried to redact such strings with
|
|
28
|
+
* a regex and leaked a credential four times over as many review rounds —
|
|
29
|
+
* through the first `@` only, through an empty userinfo, through a
|
|
30
|
+
* host-less parse, and through an authority that did not start at offset
|
|
31
|
+
* zero. Nothing short of a parser can tell userinfo from a path in a
|
|
32
|
+
* malformed string, so this follows the precedent already set for proxy
|
|
33
|
+
* URLs in `rest/errors.ts` and declines to echo it at all. Callers name the
|
|
34
|
+
* configuration key and file that produced the value instead, which is
|
|
35
|
+
* where the reader would go to look anyway.
|
|
36
|
+
*/
|
|
37
|
+
export declare function redactUrl(url: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Where the credentials sent with a request came from: a nerf-darted
|
|
40
|
+
* config entry, or userinfo embedded in the URL itself.
|
|
41
|
+
*
|
|
42
|
+
* The `url` case carries a whole `UrlOrigin` rather than mirroring its
|
|
43
|
+
* members, because the two must agree on every variant and a hand-kept
|
|
44
|
+
* copy did not: a variant added to `UrlOrigin` alone once reported
|
|
45
|
+
* registry-issued credentials as coming from a config line that contained
|
|
46
|
+
* none. Reusing the type makes the compiler enforce what review had to.
|
|
47
|
+
*/
|
|
48
|
+
export type SentCredentials = {
|
|
49
|
+
from: 'config';
|
|
50
|
+
keys: string[];
|
|
51
|
+
} | {
|
|
52
|
+
from: 'url';
|
|
53
|
+
origin: UrlOrigin;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Where a tarball URL came from: the lockfile recorded it verbatim, the
|
|
57
|
+
* registry returned it in this package's metadata, or the CLI built it from
|
|
58
|
+
* a registry. `registryKey` is absent when nothing configured one and the
|
|
59
|
+
* public npm registry was assumed.
|
|
60
|
+
*
|
|
61
|
+
* Read both to attribute credentials the URL itself carries and to say
|
|
62
|
+
* which setting produced a URL nothing can be fetched from — and the two
|
|
63
|
+
* answers differ, so the variants are not interchangeable: a metadata URL
|
|
64
|
+
* is the registry's to fix, not the project's.
|
|
65
|
+
*/
|
|
66
|
+
export type UrlOrigin = RecordedUrlOrigin | {
|
|
67
|
+
registryKey?: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* A URL this CLI did not compose: something else handed it over already
|
|
71
|
+
* formed, so it can be unusable however it likes.
|
|
72
|
+
*
|
|
73
|
+
* A URL the CLI builds itself cannot be. The registry it is built from is
|
|
74
|
+
* checked first, and appending a path to a URL that parses with a host
|
|
75
|
+
* leaves both intact — so those origins never reach a message about an
|
|
76
|
+
* unusable URL, and are not in this type.
|
|
77
|
+
*/
|
|
78
|
+
export type RecordedUrlOrigin = {
|
|
79
|
+
lockfile: string;
|
|
80
|
+
} | {
|
|
81
|
+
metadata: {
|
|
82
|
+
registryKey?: string;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Says where an unusable URL came from, and therefore whose it is to fix.
|
|
87
|
+
* The advice has to match the branch: telling someone to correct their
|
|
88
|
+
* registry setting when the bad value came out of the lockfile sends them
|
|
89
|
+
* to a setting that is already correct.
|
|
90
|
+
*/
|
|
91
|
+
export declare function describeUnusableUrlOrigin(origin: RecordedUrlOrigin, npmrc: LoadedNpmrcConfig): string;
|
|
92
|
+
/** What a redirect did to the credentials on a request. */
|
|
93
|
+
export interface RedirectOutcome {
|
|
94
|
+
/** The host the request was last redirected to. */
|
|
95
|
+
host?: string;
|
|
96
|
+
/** True when credentials were sent but did not survive the hop. */
|
|
97
|
+
credentialsDropped?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Names config keys and where they came from, for a hint sentence. Keys are
|
|
101
|
+
* listed individually because precedence is per key: the halves of a
|
|
102
|
+
* `username`/`_password` pair can come from different sources.
|
|
103
|
+
*/
|
|
104
|
+
export declare function describeConfigKeys(keys: string[], npmrc: LoadedNpmrcConfig): string;
|
|
105
|
+
/**
|
|
106
|
+
* Explains an HTTP failure that authentication could account for.
|
|
107
|
+
*
|
|
108
|
+
* 404 gets the same treatment as 401/403 because registries routinely hide
|
|
109
|
+
* packages the caller is not authorized to see behind a 404 — npmjs does —
|
|
110
|
+
* which otherwise reads as "this package does not exist" and sends people
|
|
111
|
+
* looking in entirely the wrong place. The wording stays hedged for 404,
|
|
112
|
+
* where a genuinely missing package is equally likely.
|
|
113
|
+
*
|
|
114
|
+
* Whenever credentials were sent, the message names where they came from.
|
|
115
|
+
* They can come from any of several files or an environment variable, so
|
|
116
|
+
* "your credentials were rejected" without saying which source supplied
|
|
117
|
+
* them leaves the reader exactly as stuck as a bare 404.
|
|
118
|
+
*/
|
|
119
|
+
export declare function downloadFailureHint(status: number | undefined, sent: SentCredentials | undefined, npmrc: LoadedNpmrcConfig, redirect?: RedirectOutcome): string;
|
|
120
|
+
/**
|
|
121
|
+
* Names any config file that existed but could not be read, as a sentence
|
|
122
|
+
* with a leading space or the empty string.
|
|
123
|
+
*
|
|
124
|
+
* Worth saying on any failure a credential could explain, not only the ones
|
|
125
|
+
* that got as far as a status code: a skipped `auth.ini` is invisible
|
|
126
|
+
* otherwise, and it is the likeliest thing to be missing when a private
|
|
127
|
+
* package cannot be resolved at all.
|
|
128
|
+
*/
|
|
129
|
+
export declare function describeUnreadableConfig(npmrc: LoadedNpmrcConfig): string;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { NPM_CONFIG_ENV_PREFIX } from './npmrc.js';
|
|
2
|
+
import { FETCHABLE_URL_REQUIREMENT, parseFetchableUrl } from './url.js';
|
|
3
|
+
/**
|
|
4
|
+
* Joins up to 8 items, appending `<overflow>N more` for the rest — the
|
|
5
|
+
* uniform truncation for user-facing lists of packages, versions and
|
|
6
|
+
* reasons.
|
|
7
|
+
*/
|
|
8
|
+
export function capList(items, separator, overflow) {
|
|
9
|
+
const shown = items.slice(0, 8).join(separator);
|
|
10
|
+
return items.length > 8 ? `${shown}${overflow}${items.length - 8} more` : shown;
|
|
11
|
+
}
|
|
12
|
+
/** Quotes and joins a list of names for a message. */
|
|
13
|
+
export function quotedList(names) {
|
|
14
|
+
return capList(names.map(name => `'${name}'`), ', ', ' and ');
|
|
15
|
+
}
|
|
16
|
+
/** Stand-in for a URL that cannot be shown without risking a credential. */
|
|
17
|
+
export const UNPRINTABLE_URL = '(withheld: unparseable and may contain credentials)';
|
|
18
|
+
/**
|
|
19
|
+
* Rebuilds a URL from the parts that cannot carry a credential, so it can
|
|
20
|
+
* safely appear in error messages and logs.
|
|
21
|
+
*
|
|
22
|
+
* Only scheme and host survive. Userinfo, path, query and fragment are
|
|
23
|
+
* dropped by construction rather than stripped: a registry URL may embed a
|
|
24
|
+
* token in its userinfo, a pre-signed CDN URL puts its signature in the
|
|
25
|
+
* query, and some registries take a token as a PATH segment
|
|
26
|
+
* (`https://host/<token>/npm/`). The path is the component least worth
|
|
27
|
+
* keeping anyway — every message that shows a URL already names the
|
|
28
|
+
* package and version separately, which is what the path encodes.
|
|
29
|
+
*
|
|
30
|
+
* A string that does not parse, parses without a host, or names a scheme
|
|
31
|
+
* nothing here fetches over yields the placeholder instead — deliberately
|
|
32
|
+
* the same rule as what may be requested, so a URL is echoable exactly when
|
|
33
|
+
* it was fetchable. Earlier revisions tried to redact such strings with
|
|
34
|
+
* a regex and leaked a credential four times over as many review rounds —
|
|
35
|
+
* through the first `@` only, through an empty userinfo, through a
|
|
36
|
+
* host-less parse, and through an authority that did not start at offset
|
|
37
|
+
* zero. Nothing short of a parser can tell userinfo from a path in a
|
|
38
|
+
* malformed string, so this follows the precedent already set for proxy
|
|
39
|
+
* URLs in `rest/errors.ts` and declines to echo it at all. Callers name the
|
|
40
|
+
* configuration key and file that produced the value instead, which is
|
|
41
|
+
* where the reader would go to look anyway.
|
|
42
|
+
*/
|
|
43
|
+
export function redactUrl(url) {
|
|
44
|
+
// `origin` is deliberately not used to rebuild it: that is the string
|
|
45
|
+
// "null" for non-special schemes.
|
|
46
|
+
const parsed = parseFetchableUrl(url);
|
|
47
|
+
return parsed === undefined ? UNPRINTABLE_URL : `${parsed.protocol}//${parsed.host}`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Names the registry a URL came from, by the key that configured it or as
|
|
51
|
+
* the assumed default when nothing did.
|
|
52
|
+
*/
|
|
53
|
+
function describeRegistrySource(registryKey, npmrc) {
|
|
54
|
+
return registryKey !== undefined
|
|
55
|
+
? `the registry configured by ${describeConfigKeys([registryKey], npmrc)}`
|
|
56
|
+
: 'the default registry';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Says where an unusable URL came from, and therefore whose it is to fix.
|
|
60
|
+
* The advice has to match the branch: telling someone to correct their
|
|
61
|
+
* registry setting when the bad value came out of the lockfile sends them
|
|
62
|
+
* to a setting that is already correct.
|
|
63
|
+
*/
|
|
64
|
+
export function describeUnusableUrlOrigin(origin, npmrc) {
|
|
65
|
+
if ('lockfile' in origin) {
|
|
66
|
+
return `It was recorded in '${origin.lockfile}', whose tarball URL for this package`
|
|
67
|
+
+ ` is not ${FETCHABLE_URL_REQUIREMENT}.`;
|
|
68
|
+
}
|
|
69
|
+
const registry = describeRegistrySource(origin.metadata.registryKey, npmrc);
|
|
70
|
+
const whose = origin.metadata.registryKey !== undefined
|
|
71
|
+
? `so check that the setting points at the registry you meant before taking it up with whoever runs it.`
|
|
72
|
+
: `and nothing here configures a registry, so this came from the public one.`;
|
|
73
|
+
return `It came from the package metadata served by ${registry}, which returned a tarball URL`
|
|
74
|
+
+ ` that is not ${FETCHABLE_URL_REQUIREMENT}. The URL is the registry's to correct, ${whose}`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Names config keys and where they came from, for a hint sentence. Keys are
|
|
78
|
+
* listed individually because precedence is per key: the halves of a
|
|
79
|
+
* `username`/`_password` pair can come from different sources.
|
|
80
|
+
*/
|
|
81
|
+
export function describeConfigKeys(keys, npmrc) {
|
|
82
|
+
const described = keys.map(key => {
|
|
83
|
+
const origin = npmrc.origins.get(key);
|
|
84
|
+
switch (origin?.kind) {
|
|
85
|
+
// Name the variable verbatim: the stored key has the `npm_config_`
|
|
86
|
+
// prefix stripped and may be case-folded, so echoing it would name
|
|
87
|
+
// nothing the user can search their environment for.
|
|
88
|
+
case 'env':
|
|
89
|
+
return `the '${origin.variable}' environment variable`;
|
|
90
|
+
case 'file':
|
|
91
|
+
return `'${key}' in '${origin.path}'`;
|
|
92
|
+
default:
|
|
93
|
+
return `'${key}'`;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return capList(described, ', ', ' and ');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The places a credential could have been configured, highest precedence
|
|
100
|
+
* first. The environment channel is always consulted and outranks every
|
|
101
|
+
* file, so a list that omits it sends people to edit files that cannot win.
|
|
102
|
+
*/
|
|
103
|
+
function describeConfigSources(npmrc) {
|
|
104
|
+
return quotedList([
|
|
105
|
+
`${NPM_CONFIG_ENV_PREFIX}* environment variables`,
|
|
106
|
+
...npmrc.files,
|
|
107
|
+
]);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Names where the credentials on a request came from, as a sentence tail
|
|
111
|
+
* ending in a full stop.
|
|
112
|
+
*/
|
|
113
|
+
function describeSentCredentials(sent, npmrc) {
|
|
114
|
+
if (sent.from === 'config') {
|
|
115
|
+
return `${describeConfigKeys(sent.keys, npmrc)}.`;
|
|
116
|
+
}
|
|
117
|
+
const { origin } = sent;
|
|
118
|
+
if ('lockfile' in origin) {
|
|
119
|
+
return `the tarball URL recorded in '${origin.lockfile}'.`;
|
|
120
|
+
}
|
|
121
|
+
if ('metadata' in origin) {
|
|
122
|
+
return `the tarball URL that ${describeRegistrySource(origin.metadata.registryKey, npmrc)} returned`
|
|
123
|
+
+ ` in this package's metadata, so they were issued by that registry rather than configured here.`;
|
|
124
|
+
}
|
|
125
|
+
return `the URL of ${describeRegistrySource(origin.registryKey, npmrc)}.`;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Explains an HTTP failure that authentication could account for.
|
|
129
|
+
*
|
|
130
|
+
* 404 gets the same treatment as 401/403 because registries routinely hide
|
|
131
|
+
* packages the caller is not authorized to see behind a 404 — npmjs does —
|
|
132
|
+
* which otherwise reads as "this package does not exist" and sends people
|
|
133
|
+
* looking in entirely the wrong place. The wording stays hedged for 404,
|
|
134
|
+
* where a genuinely missing package is equally likely.
|
|
135
|
+
*
|
|
136
|
+
* Whenever credentials were sent, the message names where they came from.
|
|
137
|
+
* They can come from any of several files or an environment variable, so
|
|
138
|
+
* "your credentials were rejected" without saying which source supplied
|
|
139
|
+
* them leaves the reader exactly as stuck as a bare 404.
|
|
140
|
+
*/
|
|
141
|
+
export function downloadFailureHint(status, sent, npmrc, redirect = {}) {
|
|
142
|
+
if (status !== 401 && status !== 403 && status !== 404) {
|
|
143
|
+
// The URL in the message is the one that was requested; whatever the
|
|
144
|
+
// status, say so when something else handled it. Without a status
|
|
145
|
+
// nothing answered at all, so the hop is reported without claiming it
|
|
146
|
+
// produced the failure.
|
|
147
|
+
if (redirect.host === undefined) {
|
|
148
|
+
return '';
|
|
149
|
+
}
|
|
150
|
+
return status === undefined
|
|
151
|
+
? ` The request was redirected to '${redirect.host}' before it failed.`
|
|
152
|
+
: ` The request was redirected to '${redirect.host}', which is what answered.`;
|
|
153
|
+
}
|
|
154
|
+
const sentences = [];
|
|
155
|
+
if (redirect.credentialsDropped === true) {
|
|
156
|
+
// Never say the credentials were rejected: the host that answered never
|
|
157
|
+
// saw them, and blaming them sends the reader to rotate a working
|
|
158
|
+
// token. A redirect to an unauthenticated CDN is normal for GitHub
|
|
159
|
+
// Packages and for Artifactory or Nexus fronted by object storage, so
|
|
160
|
+
// this is often not the fault at all — hence the pointer to the
|
|
161
|
+
// redirect target rather than a verdict about it.
|
|
162
|
+
sentences.push(`The request was redirected to '${redirect.host}', and the credentials were dropped rather`
|
|
163
|
+
+ ` than forwarded there, so that host answered without them. This is normal when a registry`
|
|
164
|
+
+ ` redirects to a pre-signed URL; look at what that host returned.`);
|
|
165
|
+
if (sent !== undefined) {
|
|
166
|
+
sentences.push(`The credentials the original host received came from ${describeSentCredentials(sent, npmrc)}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (sent === undefined) {
|
|
170
|
+
sentences.push(`No credentials for this registry were found in ${describeConfigSources(npmrc)}.`);
|
|
171
|
+
if (status === 404) {
|
|
172
|
+
sentences.push(`A registry may answer 404 for a package you are not authorized to see, so the package`
|
|
173
|
+
+ ` may exist but be invisible without credentials.`);
|
|
174
|
+
}
|
|
175
|
+
if (redirect.host !== undefined) {
|
|
176
|
+
// Without this the reader is told to configure credentials for a host
|
|
177
|
+
// that never asked for any, when the status came from elsewhere.
|
|
178
|
+
sentences.push(`Note that the request was redirected to '${redirect.host}', which is what answered.`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
if (status === 404) {
|
|
183
|
+
sentences.push(`Credentials were sent but did not grant access, so either the package does not exist`
|
|
184
|
+
+ ` or the credentials do not cover it.`);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
sentences.push(`The credentials sent for this registry were rejected — an expired token fails this way.`);
|
|
188
|
+
}
|
|
189
|
+
sentences.push(`They came from ${describeSentCredentials(sent, npmrc)}`);
|
|
190
|
+
if (redirect.host !== undefined) {
|
|
191
|
+
sentences.push(`They were carried through a redirect to '${redirect.host}', which is what answered.`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return ` ${sentences.join(' ')}${describeUnreadableConfig(npmrc)}`;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Names any config file that existed but could not be read, as a sentence
|
|
198
|
+
* with a leading space or the empty string.
|
|
199
|
+
*
|
|
200
|
+
* Worth saying on any failure a credential could explain, not only the ones
|
|
201
|
+
* that got as far as a status code: a skipped `auth.ini` is invisible
|
|
202
|
+
* otherwise, and it is the likeliest thing to be missing when a private
|
|
203
|
+
* package cannot be resolved at all.
|
|
204
|
+
*/
|
|
205
|
+
export function describeUnreadableConfig(npmrc) {
|
|
206
|
+
if (npmrc.unreadable.length === 0) {
|
|
207
|
+
return '';
|
|
208
|
+
}
|
|
209
|
+
return ` Note that ${quotedList(npmrc.unreadable)} could not be read, so any credentials it holds`
|
|
210
|
+
+ ` were not used.`;
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../../src/services/embedded-packages/diagnostics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PlannedTarball } from './materializer.js';
|
|
2
|
+
export interface TarballLockfileFilterResult {
|
|
3
|
+
kept: PlannedTarball[];
|
|
4
|
+
dropped: PlannedTarball[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Splits a planned tarball set by `name@version` presence in a lockfile.
|
|
8
|
+
*
|
|
9
|
+
* Used after the bundled lockfile has been pruned to the code bundle's
|
|
10
|
+
* contents: a pruned lockfile's resolutions are verified to be a subset of
|
|
11
|
+
* the original's (no new entries, no version changes), so filtering the
|
|
12
|
+
* originally planned set by presence is exactly equivalent to re-running
|
|
13
|
+
* spec matching against the pruned lockfile.
|
|
14
|
+
*
|
|
15
|
+
* Fail-safe: if the lockfile content cannot be parsed — unexpected, since
|
|
16
|
+
* a pruned lockfile has already passed the pruner's own parse and
|
|
17
|
+
* verification — every tarball is kept (the pre-filter superset is the
|
|
18
|
+
* previous behavior) and the failure is debug-logged.
|
|
19
|
+
*/
|
|
20
|
+
export declare function filterTarballsByLockfile(tarballs: PlannedTarball[], lockfileContent: string, lockfileName: string): TarballLockfileFilterResult;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Debug from 'debug';
|
|
2
|
+
import { parseLockfilePackagesContent } from './lockfile-packages.js';
|
|
3
|
+
const debug = Debug('checkly:cli:services:embedded-packages:lockfile-filter');
|
|
4
|
+
/**
|
|
5
|
+
* Splits a planned tarball set by `name@version` presence in a lockfile.
|
|
6
|
+
*
|
|
7
|
+
* Used after the bundled lockfile has been pruned to the code bundle's
|
|
8
|
+
* contents: a pruned lockfile's resolutions are verified to be a subset of
|
|
9
|
+
* the original's (no new entries, no version changes), so filtering the
|
|
10
|
+
* originally planned set by presence is exactly equivalent to re-running
|
|
11
|
+
* spec matching against the pruned lockfile.
|
|
12
|
+
*
|
|
13
|
+
* Fail-safe: if the lockfile content cannot be parsed — unexpected, since
|
|
14
|
+
* a pruned lockfile has already passed the pruner's own parse and
|
|
15
|
+
* verification — every tarball is kept (the pre-filter superset is the
|
|
16
|
+
* previous behavior) and the failure is debug-logged.
|
|
17
|
+
*/
|
|
18
|
+
export function filterTarballsByLockfile(tarballs, lockfileContent, lockfileName) {
|
|
19
|
+
let present;
|
|
20
|
+
try {
|
|
21
|
+
const packages = parseLockfilePackagesContent(lockfileContent, lockfileName);
|
|
22
|
+
present = new Set(packages.registry.map(pkg => `${pkg.name}@${pkg.version}`));
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
debug(`Could not parse '${lockfileName}' for tarball filtering, keeping all tarballs: ${err}`);
|
|
26
|
+
return { kept: [...tarballs], dropped: [] };
|
|
27
|
+
}
|
|
28
|
+
const kept = [];
|
|
29
|
+
const dropped = [];
|
|
30
|
+
for (const tarball of tarballs) {
|
|
31
|
+
if (present.has(`${tarball.name}@${tarball.version}`)) {
|
|
32
|
+
kept.push(tarball);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
dropped.push(tarball);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { kept, dropped };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=lockfile-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile-filter.js","sourceRoot":"","sources":["../../../src/services/embedded-packages/lockfile-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAA;AAGrE,MAAM,KAAK,GAAG,KAAK,CAAC,wDAAwD,CAAC,CAAA;AAO7E;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAA0B,EAC1B,eAAuB,EACvB,YAAoB;IAEpB,IAAI,OAAoB,CAAA;IACxB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,4BAA4B,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;QAC5E,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAC/E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,oBAAoB,YAAY,kDAAkD,GAAG,EAAE,CAAC,CAAA;QAC9F,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IAC7C,CAAC;IAED,MAAM,IAAI,GAAqB,EAAE,CAAA;IACjC,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC"}
|