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.
Files changed (85) hide show
  1. package/dist/ai-context/skills-command/references/configure-playwright-checks.md +24 -19
  2. package/dist/commands/debug/parse-project.js +3 -0
  3. package/dist/commands/debug/parse-project.js.map +1 -1
  4. package/dist/commands/deploy.js +3 -0
  5. package/dist/commands/deploy.js.map +1 -1
  6. package/dist/commands/pw-test.js +3 -0
  7. package/dist/commands/pw-test.js.map +1 -1
  8. package/dist/commands/test.js +3 -0
  9. package/dist/commands/test.js.map +1 -1
  10. package/dist/config.d.ts +1 -1
  11. package/dist/config.js.map +1 -1
  12. package/dist/constructs/playwright-check-bundle.d.ts +5 -5
  13. package/dist/constructs/playwright-check-bundle.js.map +1 -1
  14. package/dist/constructs/project.js +5 -2
  15. package/dist/constructs/project.js.map +1 -1
  16. package/dist/constructs/session.d.ts +2 -1
  17. package/dist/constructs/session.js +2 -1
  18. package/dist/constructs/session.js.map +1 -1
  19. package/dist/index.d.ts +1 -0
  20. package/dist/services/check-parser/bundler.d.ts +79 -8
  21. package/dist/services/check-parser/bundler.js +567 -9
  22. package/dist/services/check-parser/bundler.js.map +1 -1
  23. package/dist/services/check-parser/cache-hash.d.ts +141 -17
  24. package/dist/services/check-parser/cache-hash.js +78 -12
  25. package/dist/services/check-parser/cache-hash.js.map +1 -1
  26. package/dist/services/check-parser/faux-package.d.ts +5 -0
  27. package/dist/services/check-parser/faux-package.js +9 -1
  28. package/dist/services/check-parser/faux-package.js.map +1 -1
  29. package/dist/services/check-parser/lockfile-pruner.d.ts +104 -0
  30. package/dist/services/check-parser/lockfile-pruner.js +1107 -0
  31. package/dist/services/check-parser/lockfile-pruner.js.map +1 -0
  32. package/dist/services/check-parser/package-files/package-manager.d.ts +34 -0
  33. package/dist/services/check-parser/package-files/package-manager.js +131 -3
  34. package/dist/services/check-parser/package-files/package-manager.js.map +1 -1
  35. package/dist/services/check-parser/package-files/pnpmfile.d.ts +40 -0
  36. package/dist/services/check-parser/package-files/pnpmfile.js +322 -0
  37. package/dist/services/check-parser/package-files/pnpmfile.js.map +1 -0
  38. package/dist/services/check-parser/package-files/resolver.d.ts +6 -1
  39. package/dist/services/check-parser/package-files/resolver.js +34 -0
  40. package/dist/services/check-parser/package-files/resolver.js.map +1 -1
  41. package/dist/services/check-parser/package-files/workspace.d.ts +16 -1
  42. package/dist/services/check-parser/package-files/workspace.js +17 -2
  43. package/dist/services/check-parser/package-files/workspace.js.map +1 -1
  44. package/dist/services/check-parser/package-prune.d.ts +68 -0
  45. package/dist/services/check-parser/package-prune.js +274 -0
  46. package/dist/services/check-parser/package-prune.js.map +1 -0
  47. package/dist/services/check-parser/parser.js +9 -0
  48. package/dist/services/check-parser/parser.js.map +1 -1
  49. package/dist/services/check-parser/patched-dependencies.d.ts +133 -0
  50. package/dist/services/check-parser/patched-dependencies.js +428 -0
  51. package/dist/services/check-parser/patched-dependencies.js.map +1 -0
  52. package/dist/services/checkly-config-loader.d.ts +164 -10
  53. package/dist/services/checkly-config-loader.js +39 -0
  54. package/dist/services/checkly-config-loader.js.map +1 -1
  55. package/dist/services/embedded-packages/cache.d.ts +8 -4
  56. package/dist/services/embedded-packages/cache.js +27 -6
  57. package/dist/services/embedded-packages/cache.js.map +1 -1
  58. package/dist/services/embedded-packages/diagnostics.d.ts +129 -0
  59. package/dist/services/embedded-packages/diagnostics.js +212 -0
  60. package/dist/services/embedded-packages/diagnostics.js.map +1 -0
  61. package/dist/services/embedded-packages/lockfile-filter.d.ts +20 -0
  62. package/dist/services/embedded-packages/lockfile-filter.js +40 -0
  63. package/dist/services/embedded-packages/lockfile-filter.js.map +1 -0
  64. package/dist/services/embedded-packages/lockfile-packages.d.ts +31 -2
  65. package/dist/services/embedded-packages/lockfile-packages.js +234 -30
  66. package/dist/services/embedded-packages/lockfile-packages.js.map +1 -1
  67. package/dist/services/embedded-packages/materializer.d.ts +19 -5
  68. package/dist/services/embedded-packages/materializer.js +445 -91
  69. package/dist/services/embedded-packages/materializer.js.map +1 -1
  70. package/dist/services/embedded-packages/npmrc.d.ts +163 -21
  71. package/dist/services/embedded-packages/npmrc.js +440 -75
  72. package/dist/services/embedded-packages/npmrc.js.map +1 -1
  73. package/dist/services/embedded-packages/spec.d.ts +89 -17
  74. package/dist/services/embedded-packages/spec.js +199 -30
  75. package/dist/services/embedded-packages/spec.js.map +1 -1
  76. package/dist/services/embedded-packages/url.d.ts +39 -0
  77. package/dist/services/embedded-packages/url.js +60 -0
  78. package/dist/services/embedded-packages/url.js.map +1 -0
  79. package/dist/services/playwright-project-bundler.js +27 -23
  80. package/dist/services/playwright-project-bundler.js.map +1 -1
  81. package/dist/services/runner/registries.d.ts +144 -0
  82. package/dist/services/runner/registries.js +232 -0
  83. package/dist/services/runner/registries.js.map +1 -0
  84. package/oclif.manifest.json +1 -1
  85. package/package.json +5 -5
@@ -0,0 +1,428 @@
1
+ import path from 'node:path';
2
+ import { isDeepStrictEqual } from 'node:util';
3
+ import Debug from 'debug';
4
+ import { isMap, parse as parseYaml, parseDocument } from 'yaml';
5
+ import { pathToPosix } from '../util.js';
6
+ const debug = Debug('checkly:cli:services:check-parser:patched-dependencies');
7
+ /**
8
+ * Serialization options that make a `yaml` round trip of a pnpm lockfile
9
+ * byte-identical to what pnpm itself writes. `lineWidth: 0` disables the
10
+ * folding that would otherwise rewrap long `resolution:` lines, and
11
+ * `flowCollectionPadding: false` reproduces pnpm's unpadded `{integrity: ...}`
12
+ * spelling. Both are required; with either one at its default the serializer
13
+ * reformats lines it was not asked to touch.
14
+ */
15
+ const YAML_STRINGIFY_OPTIONS = { lineWidth: 0, flowCollectionPadding: false };
16
+ const PATCHED_DEPENDENCIES = 'patchedDependencies';
17
+ /**
18
+ * The directory pnpm's own `pnpm patch-commit` writes patches to, relative to
19
+ * the workspace root. Shared so that the auto-include that bundles patches and
20
+ * the filtering that removes them cannot drift apart: widening one without the
21
+ * other would silently leave orphaned patch files in every bundle.
22
+ */
23
+ export const PNPM_PATCHES_DIR = 'patches';
24
+ /**
25
+ * Whether an archive path names a patch file the filtering may remove from a
26
+ * bundle: a `.patch` directly under {@link PNPM_PATCHES_DIR}. A declaration
27
+ * may point anywhere, including at a file bundled for an unrelated reason, so
28
+ * only the conventional location is removable.
29
+ */
30
+ export function isRemovablePatchPath(archivePath) {
31
+ return new RegExp(`^${PNPM_PATCHES_DIR}/[^/]+\\.patch$`).test(archivePath);
32
+ }
33
+ /**
34
+ * Reads a config's `patchedDependencies` map. Returns an empty map when the
35
+ * config declares none, and `undefined` when the file cannot be parsed or the
36
+ * map is not shaped as expected — callers treat that as "do not filter".
37
+ */
38
+ export function readPatchedDependencies(config) {
39
+ let parsed;
40
+ try {
41
+ parsed = config.kind === 'package.json'
42
+ ? JSON.parse(config.content)
43
+ // An empty or comment-only YAML document parses to null: an ordinary
44
+ // pnpm-workspace.yaml that declares no settings, not an unreadable file.
45
+ // JSON has no such spelling — JSON.parse throws on empty input.
46
+ : parseYaml(config.content) ?? {};
47
+ }
48
+ catch (err) {
49
+ debug(`Could not parse ${config.archivePath}: ${err}`);
50
+ return undefined;
51
+ }
52
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
53
+ return undefined;
54
+ }
55
+ const container = config.kind === 'package.json'
56
+ ? parsed.pnpm
57
+ : parsed;
58
+ if (container === undefined || container === null) {
59
+ return [];
60
+ }
61
+ if (typeof container !== 'object' || Array.isArray(container)) {
62
+ return undefined;
63
+ }
64
+ const section = container[PATCHED_DEPENDENCIES];
65
+ if (section === undefined || section === null) {
66
+ return [];
67
+ }
68
+ if (typeof section !== 'object' || Array.isArray(section)) {
69
+ return undefined;
70
+ }
71
+ const declarations = [];
72
+ for (const [key, value] of Object.entries(section)) {
73
+ // pnpm only accepts a path string here. Anything else is a config this
74
+ // code does not understand, so it declines to touch the bundle at all.
75
+ if (typeof value !== 'string') {
76
+ return undefined;
77
+ }
78
+ declarations.push({ key, patchPath: value });
79
+ }
80
+ return declarations;
81
+ }
82
+ /**
83
+ * Reads a lockfile's `patchedDependencies` section as key → patch hash.
84
+ * pnpm 10 records `{ hash, path }` objects and pnpm 11 a bare hash string;
85
+ * both are accepted. Returns `undefined` when the lockfile cannot be parsed.
86
+ */
87
+ export function readLockfilePatchHashes(lockfileContent) {
88
+ let parsed;
89
+ try {
90
+ parsed = parseYaml(lockfileContent);
91
+ }
92
+ catch (err) {
93
+ debug(`Could not parse the lockfile: ${err}`);
94
+ return undefined;
95
+ }
96
+ const hashes = new Map();
97
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
98
+ return undefined;
99
+ }
100
+ const section = parsed[PATCHED_DEPENDENCIES];
101
+ if (section === undefined || section === null) {
102
+ return hashes;
103
+ }
104
+ if (typeof section !== 'object' || Array.isArray(section)) {
105
+ return undefined;
106
+ }
107
+ for (const [key, value] of Object.entries(section)) {
108
+ const hash = typeof value === 'string' ? value : value?.hash;
109
+ if (typeof hash !== 'string' || hash === '') {
110
+ return undefined;
111
+ }
112
+ hashes.set(key, hash);
113
+ }
114
+ return hashes;
115
+ }
116
+ /**
117
+ * Finds the single config whose `patchedDependencies` the bundle should be
118
+ * filtered against, or `undefined` when there is nothing to do or the configs
119
+ * cannot be used.
120
+ *
121
+ * Declining when more than one config declares a non-empty map is deliberate:
122
+ * pnpm picks ONE site and ignores the other wholesale, and which site wins
123
+ * depends on the pnpm major (10 prefers `package.json`, 11 ignores it
124
+ * entirely). Editing the losing site is not merely useless — emptying the
125
+ * winning one would promote the loser, changing which patches apply.
126
+ */
127
+ function findDeclaringConfig(configs) {
128
+ const declaring = [];
129
+ for (const config of configs) {
130
+ const declarations = readPatchedDependencies(config);
131
+ if (declarations === undefined) {
132
+ return undefined;
133
+ }
134
+ if (declarations.length > 0) {
135
+ declaring.push({ config, declarations });
136
+ }
137
+ }
138
+ if (declaring.length > 1) {
139
+ debug('More than one config declares patchedDependencies; leaving the bundle alone');
140
+ return undefined;
141
+ }
142
+ return declaring[0];
143
+ }
144
+ /**
145
+ * Whether a patch declaration still applies to something in `lockfileContent`.
146
+ *
147
+ * pnpm records the applied patch by hash: the `patchedDependencies` section
148
+ * pins `key → hash`, and that hash reappears as `patch_hash=<hash>` in the
149
+ * importer, snapshot and package entries of every package the patch was
150
+ * applied to. A declaration that applies to nothing keeps its section entry —
151
+ * the section mirrors the config, not the dependency graph — but its hash
152
+ * appears nowhere else, which makes the marker the sole discriminator. A
153
+ * whole-file search is safe because the section's own value never contains
154
+ * the literal `patch_hash=`.
155
+ */
156
+ function hasMarker(hash, lockfileContent) {
157
+ return hash !== undefined && lockfileContent.includes(`patch_hash=${hash}`);
158
+ }
159
+ /**
160
+ * Whether the prune is what stopped a patch from applying.
161
+ *
162
+ * Deliberately differential rather than a bare absence test on the pruned
163
+ * lockfile. Absence alone would mean that a lockfile this module cannot read
164
+ * markers out of — a future pnpm that keeps the `9` version string but spells
165
+ * them differently — reads as "nothing applies anywhere" and every declaration
166
+ * is stripped at once, which is the one outcome the module exists to prevent.
167
+ * Requiring the marker in the original first makes that case drop nothing.
168
+ *
169
+ * The pruned side falls back to the original's hash because a lockfile can
170
+ * lose the `patchedDependencies` section while keeping its markers; without
171
+ * the fallback such a patch would read as no longer applied.
172
+ */
173
+ function droppedByPrune(key, prunedHashes, originalHashes, originalLockfileContent, prunedLockfileContent) {
174
+ const originalHash = originalHashes.get(key);
175
+ if (!hasMarker(originalHash, originalLockfileContent)) {
176
+ return false;
177
+ }
178
+ return !hasMarker(prunedHashes.get(key) ?? originalHash, prunedLockfileContent);
179
+ }
180
+ /**
181
+ * Resolves a declared patch path to its archive path, or `undefined` when it
182
+ * escapes the workspace root (the archive's own root) and therefore does not
183
+ * name a bundle entry this code may remove.
184
+ */
185
+ function patchArchivePath(patchPath) {
186
+ // Traversal is judged on the path AS WRITTEN, before any normalization:
187
+ // pathToPosix normalizes internally, which collapses `..` segments and would
188
+ // hide a path that leaves the root and comes back
189
+ // (`patches/sub/../../package.json` collapses to `package.json`, naming a
190
+ // bundle file that is not a patch at all).
191
+ if (patchPath.split(/[/\\]/).includes('..')) {
192
+ return undefined;
193
+ }
194
+ const normalized = pathToPosix(patchPath);
195
+ if (path.posix.isAbsolute(normalized)) {
196
+ return undefined;
197
+ }
198
+ // `.` (what an empty path normalizes to) and a trailing slash name a
199
+ // directory, not a patch file, so they must never reach a caller that
200
+ // deletes bundle entries.
201
+ if (normalized === '.' || normalized.endsWith('/')) {
202
+ return undefined;
203
+ }
204
+ // pathToPosix only rewrites the platform's own separator and strips C:/D:
205
+ // drive prefixes, so a spelling from another platform can survive looking
206
+ // relative yet still denote a path this comparison cannot align with.
207
+ if (normalized.includes('\\') || /^[A-Za-z]:/.test(normalized)) {
208
+ return undefined;
209
+ }
210
+ return normalized;
211
+ }
212
+ /**
213
+ * Computes the patch declarations a bundle should stop shipping, together with
214
+ * the rewritten files that carry the removal. Returns `undefined` whenever the
215
+ * evidence is incomplete or an edit cannot be verified — the caller then ships
216
+ * the bundle unchanged, which is always safe.
217
+ */
218
+ export function planPatchFilter(options) {
219
+ const { configs, originalLockfileContent, prunedLockfileContent } = options;
220
+ const declaring = findDeclaringConfig(configs);
221
+ if (declaring === undefined) {
222
+ return undefined;
223
+ }
224
+ const originalHashes = readLockfilePatchHashes(originalLockfileContent);
225
+ const prunedHashes = readLockfilePatchHashes(prunedLockfileContent);
226
+ if (originalHashes === undefined || prunedHashes === undefined) {
227
+ return undefined;
228
+ }
229
+ const unusedKeys = [];
230
+ // Both sets hold ARCHIVE paths, never the raw spelling: two declarations can
231
+ // point at one file with different spellings (`./patches/x.patch` and
232
+ // `patches/x.patch`), and comparing raw strings would drop a file a
233
+ // surviving declaration still needs.
234
+ const keptArchivePaths = new Set();
235
+ const candidateArchivePaths = new Set();
236
+ // A surviving declaration whose path resolves outside the bundle root cannot
237
+ // be compared against the in-root candidates at all, so no file is dropped
238
+ // in that case. The declarations and lockfile entries still go; an
239
+ // unreferenced patch file left in the bundle is inert.
240
+ let keptPathEscapesRoot = false;
241
+ for (const declaration of declaring.declarations) {
242
+ const archivePath = patchArchivePath(declaration.patchPath);
243
+ // A key the project's own lockfile never recorded is no evidence of
244
+ // anything: the pnpm that wrote it may simply not read the site the key
245
+ // was declared in. Removing it would silently unpatch a dependency that a
246
+ // different pnpm on the runner would patch.
247
+ const recorded = originalHashes.has(declaration.key);
248
+ if (!recorded) {
249
+ debug(`Patch '${declaration.key}' is not recorded in the project's lockfile; leaving it alone`);
250
+ }
251
+ const dropped = recorded && droppedByPrune(declaration.key, prunedHashes, originalHashes, originalLockfileContent, prunedLockfileContent);
252
+ if (!dropped) {
253
+ if (archivePath === undefined) {
254
+ keptPathEscapesRoot = true;
255
+ }
256
+ else {
257
+ keptArchivePaths.add(archivePath);
258
+ }
259
+ continue;
260
+ }
261
+ unusedKeys.push(declaration.key);
262
+ if (archivePath === undefined) {
263
+ debug(`Patch path '${declaration.patchPath}' resolves outside the bundle root; leaving it alone`);
264
+ }
265
+ else {
266
+ candidateArchivePaths.add(archivePath);
267
+ }
268
+ }
269
+ if (unusedKeys.length === 0) {
270
+ return undefined;
271
+ }
272
+ const removed = new Set(unusedKeys);
273
+ const configContent = rewriteConfig(declaring.config, removed);
274
+ if (configContent === undefined) {
275
+ return undefined;
276
+ }
277
+ const rewrittenConfig = {
278
+ archivePath: declaring.config.archivePath,
279
+ content: configContent,
280
+ };
281
+ const lockfileContent = rewriteYamlSection(prunedLockfileContent, removed);
282
+ if (lockfileContent === undefined) {
283
+ return undefined;
284
+ }
285
+ // Two declarations may share a patch file; keep it while any survivor still
286
+ // points at it.
287
+ const droppedPatchPaths = keptPathEscapesRoot
288
+ ? []
289
+ : Array.from(candidateArchivePaths).filter(archivePath => !keptArchivePaths.has(archivePath));
290
+ return { unusedKeys, rewrittenConfig, droppedPatchPaths, lockfileContent };
291
+ }
292
+ function rewriteConfig(config, removed) {
293
+ return config.kind === 'package.json'
294
+ ? rewritePackageJson(config.content, removed)
295
+ : rewriteYamlSection(config.content, removed);
296
+ }
297
+ /**
298
+ * Removes keys from a YAML document's top-level `patchedDependencies` map,
299
+ * dropping the map itself once it empties. Shared by `pnpm-workspace.yaml` and
300
+ * `pnpm-lock.yaml`, whose sections have the same shape.
301
+ *
302
+ * The result is verified structurally before it is returned: a serializer that
303
+ * reformatted or dropped anything else would ship silently, and for the
304
+ * lockfile it would also invalidate the verification the pruner already ran
305
+ * over the bytes it produced.
306
+ */
307
+ export function rewriteYamlSection(content, removed) {
308
+ // parseDocument collects syntax errors on the document rather than throwing,
309
+ // so `errors` — not a try/catch — is what rejects malformed input here.
310
+ const doc = parseDocument(content);
311
+ if (doc.errors.length > 0) {
312
+ debug(`Could not parse YAML for rewriting: ${doc.errors[0].message}`);
313
+ return undefined;
314
+ }
315
+ const section = doc.get(PATCHED_DEPENDENCIES);
316
+ if (section === undefined || section === null) {
317
+ // Nothing to delete. The prune can legitimately return a lockfile that
318
+ // carries no section at all, in which case only the config needs editing.
319
+ return content;
320
+ }
321
+ if (!isMap(section)) {
322
+ return undefined;
323
+ }
324
+ for (const key of removed) {
325
+ doc.deleteIn([PATCHED_DEPENDENCIES, key]);
326
+ }
327
+ if (section.items.length === 0) {
328
+ doc.delete(PATCHED_DEPENDENCIES);
329
+ }
330
+ const rewritten = doc.toString(YAML_STRINGIFY_OPTIONS);
331
+ return verifyRewrite(content, rewritten, removed, parseYaml);
332
+ }
333
+ function rewritePackageJson(content, removed) {
334
+ let parsed;
335
+ try {
336
+ parsed = JSON.parse(content);
337
+ }
338
+ catch (err) {
339
+ debug(`Could not parse package.json for rewriting: ${err}`);
340
+ return undefined;
341
+ }
342
+ const section = parsed?.pnpm?.[PATCHED_DEPENDENCIES];
343
+ if (section === null || typeof section !== 'object') {
344
+ return undefined;
345
+ }
346
+ for (const key of removed) {
347
+ delete section[key];
348
+ }
349
+ if (Object.keys(section).length === 0) {
350
+ delete parsed.pnpm[PATCHED_DEPENDENCIES];
351
+ }
352
+ // Unlike the YAML path, which is byte-preserving, this reformats the whole
353
+ // manifest. The bundled copy is only ever an install input — nothing reads it
354
+ // back as text — and matching the original's formatting would mean carrying a
355
+ // JSON editor for no behavioral gain.
356
+ const rewritten = JSON.stringify(parsed, null, 2);
357
+ return verifyRewrite(content, rewritten, removed, JSON.parse);
358
+ }
359
+ /**
360
+ * Asserts that a rewrite changed nothing but the intended keys, by comparing
361
+ * the reparsed result against the reparsed original with those keys deleted.
362
+ * A config can carry anything else pnpm understands — `catalog:`, `overrides`,
363
+ * `onlyBuiltDependencies` — and nothing downstream would notice it being
364
+ * mangled, so the check is what makes the edit safe to ship.
365
+ *
366
+ * Exported so that the rejection path — which no legitimate serializer output
367
+ * reaches, and which therefore cannot be driven through the callers — is
368
+ * directly testable.
369
+ *
370
+ * Package pruning keeps an analogous fail-closed verifier in
371
+ * package-prune.ts (`verifyPrunedManifest`); hardening either against a
372
+ * manifest quirk likely applies to both.
373
+ */
374
+ export function verifyRewrite(original, rewritten, removed, parse) {
375
+ let expected;
376
+ let actual;
377
+ try {
378
+ expected = parse(original);
379
+ actual = parse(rewritten);
380
+ }
381
+ catch (err) {
382
+ debug(`Could not reparse a rewritten file for verification: ${err}`);
383
+ return undefined;
384
+ }
385
+ for (const container of [expected, expected?.pnpm]) {
386
+ const section = container?.[PATCHED_DEPENDENCIES];
387
+ if (section === null || typeof section !== 'object') {
388
+ continue;
389
+ }
390
+ for (const key of removed) {
391
+ delete section[key];
392
+ }
393
+ if (Object.keys(section).length === 0) {
394
+ delete container[PATCHED_DEPENDENCIES];
395
+ }
396
+ }
397
+ if (!isDeepStrictEqual(expected, actual)) {
398
+ debug('A rewritten file did not match the expected structure; leaving the bundle alone');
399
+ return undefined;
400
+ }
401
+ return rewritten;
402
+ }
403
+ /**
404
+ * Reports declarations the shipped bundle still carries but its shipped
405
+ * lockfile no longer records — the precondition for the remote install failing
406
+ * with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`.
407
+ *
408
+ * Scoped to keys the project's original lockfile recorded, so a declaration
409
+ * the project's own pnpm never honoured is not reported as a bundling problem.
410
+ */
411
+ export function findUnrepairedPatchKeys(options) {
412
+ const { configs, originalLockfileContent, shippedLockfileContent } = options;
413
+ const originalHashes = readLockfilePatchHashes(originalLockfileContent);
414
+ const shippedHashes = readLockfilePatchHashes(shippedLockfileContent);
415
+ if (originalHashes === undefined || shippedHashes === undefined) {
416
+ return [];
417
+ }
418
+ const unrepaired = new Set();
419
+ for (const config of configs) {
420
+ for (const declaration of readPatchedDependencies(config) ?? []) {
421
+ if (originalHashes.has(declaration.key) && !shippedHashes.has(declaration.key)) {
422
+ unrepaired.add(declaration.key);
423
+ }
424
+ }
425
+ }
426
+ return Array.from(unrepaired).sort();
427
+ }
428
+ //# sourceMappingURL=patched-dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patched-dependencies.js","sourceRoot":"","sources":["../../../src/services/check-parser/patched-dependencies.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@ import type { Region } from '../index.js';
5
5
  import { ReporterType } from '../reporters/reporter.js';
6
6
  import { PlaywrightConfig } from '../constructs/playwright-config.js';
7
7
  import { FileLoader } from '../loader/index.js';
8
+ import { BundlePackagesPrune } from './check-parser/package-prune.js';
9
+ import { Registries } from './runner/registries.js';
8
10
  export type CheckConfigDefaults = Pick<CheckProps, 'activated' | 'alertChannels' | 'alertEscalationPolicy' | 'doubleCheck' | 'frequency' | 'locations' | 'muted' | 'privateLocations' | 'retryStrategy' | 'shouldFail' | 'tags'> & Pick<RuntimeCheckProps, 'environmentVariables' | 'runtimeId'> & {
9
11
  playwrightConfig?: PlaywrightConfig;
10
12
  };
@@ -12,7 +14,7 @@ export type PlaywrightSlimmedProp = Pick<PlaywrightCheckProps, 'name' | 'activat
12
14
  logicalId: string;
13
15
  playwrightConfigPath?: string;
14
16
  };
15
- export type ChecklyConfig = {
17
+ export type ChecklyConfig<UpstreamName extends string = string> = {
16
18
  /**
17
19
  * Friendly name for your project.
18
20
  */
@@ -86,19 +88,117 @@ export type ChecklyConfig = {
86
88
  * Each entry is a package name (`'@acme/private-utils'`), which embeds
87
89
  * every version of that package found in the workspace lockfile, or an
88
90
  * exact `name@version` pin (`'legacy-private-pkg@2.1.0'`). Names may
89
- * contain `*` wildcards (`'@acme/*'`, `'acme-*'`); a wildcard never
90
- * crosses the `/` scope separator. List every package the runner
91
+ * contain `*` wildcards (`'@acme/*'`, `'acme-*'`); a single `*` never
92
+ * crosses the `/` scope separator, while a `**` does — `'**'` matches
93
+ * every package, and `'**-foo'` matches names ending in `-foo` in any
94
+ * scope or none. Directly before a `/`, a `**` may together with that
95
+ * `/` also match nothing, glob-style: `'**' + '/utils'` (one string;
96
+ * split here only because `*` followed by `/` would end this comment)
97
+ * matches both `utils` and `@acme/utils`. (Earlier CLI releases
98
+ * treated a run of stars as a single `*`.) List every package the
99
+ * runner
91
100
  * cannot fetch, including private packages that only appear as
92
101
  * transitive dependencies of other private packages — dependencies of
93
102
  * listed packages are not embedded automatically.
94
103
  *
95
- * Only npm and pnpm are supported at this time: packages are resolved
96
- * against the workspace lockfile (`pnpm-lock.yaml` or
97
- * `package-lock.json`) and always verified against its recorded
98
- * integrity hashes. Changing the resolved set of embedded packages
99
- * invalidates the runner's dependency cache.
104
+ * A `!` prefix turns an entry into an exclusion, which removes the
105
+ * packages it matches from what the entries *before* it selected.
106
+ * Entries therefore apply in order: `['@acme/*', '!@acme/legacy']`
107
+ * embeds the whole scope except `@acme/legacy`, while the reverse
108
+ * order embeds the whole scope, because the exclusion runs before
109
+ * anything has been selected. An exclusion that removes nothing is a
110
+ * no-op rather than an error. Removing every package an entry
111
+ * selected also silences that entry: no "not found" error, and no
112
+ * "cannot be embedded" warning even for packages it matched but did
113
+ * not exclude — run with `DEBUG='checkly:cli:services:embedded-packages'`
114
+ * to see what it reached. Since exclusions only subtract, a list of
115
+ * nothing but exclusions selects nothing; a configuration whose
116
+ * entries select no packages at all is reported as a warning.
117
+ *
118
+ * Only npm, pnpm, bun and Yarn Berry are supported at this time:
119
+ * packages are resolved against the workspace lockfile
120
+ * (`pnpm-lock.yaml`, `package-lock.json`, the text `bun.lock` —
121
+ * bun's binary `bun.lockb` is not supported — or a Yarn Berry
122
+ * `yarn.lock`; Yarn Classic v1 lockfiles are not) and always
123
+ * verified against its recorded integrity hashes. Yarn Berry
124
+ * lockfiles record no npm tarball integrity, so it is resolved from
125
+ * the registry's package metadata instead — one small metadata
126
+ * request per embedded package on every deploy, even with a warm
127
+ * cache. Downloads read registry credentials from `npm_config_*`
128
+ * environment variables, the project, workspace-root and user
129
+ * `.npmrc` files, and pnpm's global `auth.ini` (where `pnpm login`
130
+ * writes tokens on pnpm 11 and later), including the
131
+ * scope-qualified keys `pnpm login --scope` writes. bun or yarn
132
+ * users whose credentials live solely in `bunfig.toml` or
133
+ * `.yarnrc.yml` must duplicate them into `.npmrc` or set
134
+ * `npm_config_*` — referencing a token through an environment
135
+ * variable (`${NPM_TOKEN}`), never as plaintext, because `.npmrc`
136
+ * is uploaded with the code bundle. When the bundled lockfile is pruned to the code
137
+ * bundle's contents, the embedded set follows it: packages the pruned
138
+ * lockfile no longer references — dependencies of workspace members
139
+ * that are not part of the bundle — are neither embedded nor
140
+ * downloaded, even if an entry matches them. That usually means the
141
+ * runner does not need the package at all; if the checks genuinely
142
+ * need it, make the depending workspace member part of the bundle
143
+ * rather than disabling pruning (`CHECKLY_LOCKFILE_PRUNE=0` restores
144
+ * the unfiltered set, as a last resort). Changing the resolved set of
145
+ * embedded packages invalidates the runner's dependency cache.
100
146
  */
101
147
  embed?: string[];
148
+ /**
149
+ * Dependencies to remove from the `package.json` files shipped inside
150
+ * the code bundle — the workspace root's and every bundled workspace
151
+ * member's. Applies to Playwright Check Suites only. The files on
152
+ * disk are never modified; only the bundled copies are rewritten.
153
+ *
154
+ * The manifests are rewritten before the bundled lockfile is pruned
155
+ * to the code bundle's contents, so the removed dependencies fall out
156
+ * of the bundled lockfile too. This is the escape hatch for
157
+ * dependencies that lockfile pruning alone cannot drop: with pnpm's
158
+ * `auto-install-peers`, a bundled member's unused `peerDependencies`
159
+ * are resolved as real dependencies of the regenerated lockfile even
160
+ * though the bundled code never imports them. Because the rewritten
161
+ * manifests only make sense next to a matching lockfile, the option
162
+ * requires lockfile pruning: if the bundled lockfile cannot be pruned
163
+ * in the same run — an unsupported package manager, a failed
164
+ * regeneration, or `CHECKLY_LOCKFILE_PRUNE=0` — the original
165
+ * manifests ship unchanged, with a warning. A bundle that ships no
166
+ * lockfile has nothing to fall out of sync with, so the pruned
167
+ * manifests always ship there.
168
+ *
169
+ * Accepts either an array of package name patterns, removed from
170
+ * every dependency class (`dependencies`, `devDependencies`,
171
+ * `peerDependencies` and `optionalDependencies`), or an object keyed
172
+ * by dependency class whose values are `true` (remove the whole
173
+ * class) or a pattern array (remove matching entries from that class
174
+ * only). Names may contain `*` wildcards (`'@acme/*'`, `'acme-*'`);
175
+ * a single `*` never crosses the `/` scope separator, so a bare
176
+ * `'*'` matches only unscoped names, while a `**` does cross it —
177
+ * to remove a whole class, use `true` or `['**']`, not `['*']`.
178
+ * Wildcards follow `bundle.packages.embed`'s rules, including the
179
+ * glob-style zero-segment match of a `**` directly before a `/`.
180
+ * (Earlier CLI releases treated a run of stars as a single `*`.)
181
+ * A `!` prefix turns an entry into an exclusion that
182
+ * removes what it matches from the entries *before* it selected,
183
+ * with `bundle.packages.embed`'s order-sensitive semantics:
184
+ * `['@acme/*', '!@acme/keep']` removes the scope except
185
+ * `@acme/keep`, while the reverse order removes the whole scope
186
+ * because the exclusion runs before anything has been selected. To
187
+ * remove a whole class *except* some packages, select everything
188
+ * first: `['**', '!@acme/keep']`.
189
+ * `true` cannot be combined with exclusions. Unlike
190
+ * `bundle.packages.embed` there are no
191
+ * `name@version` pins; they are rejected at config load. Removed
192
+ * `peerDependencies` take their `peerDependenciesMeta` entries with
193
+ * them, and `peerDependencies: true` clears `peerDependenciesMeta`
194
+ * entirely.
195
+ *
196
+ * Pruning is not validated against the code: you are responsible for
197
+ * not removing anything the bundled code actually needs at runtime.
198
+ * A pattern that matches nothing is not an error. Changing the
199
+ * pruned output invalidates the runner's dependency cache.
200
+ */
201
+ prune?: BundlePackagesPrune;
102
202
  };
103
203
  };
104
204
  /**
@@ -113,8 +213,10 @@ export type ChecklyConfig = {
113
213
  dependencyCache?: {
114
214
  /**
115
215
  * Optional value mixed into the code bundle's cache hash in addition
116
- * to its usual inputs (lockfile, package.json and .npmrc files, and
117
- * the resolved `bundle.packages.embed` tarball set).
216
+ * to its usual inputs the workspace's dependency-install inputs.
217
+ * The exhaustive input list lives with the hash itself; see
218
+ * `ComposeCacheHashInput` in
219
+ * `services/check-parser/cache-hash.ts`.
118
220
  * Change the value to force runners to reinstall the bundle's
119
221
  * dependencies. Setting it for the first time invalidates the cache
120
222
  * once. Numbers must be safe integers; unset and empty string leave
@@ -130,6 +232,58 @@ export type ChecklyConfig = {
130
232
  version?: string | number;
131
233
  };
132
234
  };
235
+ /**
236
+ * Configuration applied on the Checkly runner when it executes checks.
237
+ */
238
+ runner?: {
239
+ /**
240
+ * Registry routing for the dependency install of a Playwright Check
241
+ * Suite code bundle. Use this when the registries your `.npmrc` (or
242
+ * `pnpm-workspace.yaml` / `.yarnrc.yml`) points at resolve fine on
243
+ * the machine running the CLI but are unreachable from Checkly
244
+ * runners — e.g. a VPN-only mirror. When set, the runner installs
245
+ * packages through a local registry that selects upstreams according
246
+ * to these rules instead of the registries named in bundled config
247
+ * files; embedded packages (`bundle.packages.embed`) always take
248
+ * priority regardless of the rules. Applies to Playwright Check
249
+ * Suites only, and only on the runner: operations on the machine
250
+ * running the CLI — embedded-package downloads, lockfile pruning —
251
+ * still read `.npmrc` and `npm_config_*` credentials.
252
+ *
253
+ * `upstreams` names the registries the runner may fetch from. Each
254
+ * needs a base `url` (an absolute http(s) URL without query,
255
+ * fragment or inline credentials, since package paths are appended
256
+ * to it) and may carry bearer `auth`. An auth token must be exactly
257
+ * one environment variable reference in `${VAR}` syntax (e.g.
258
+ * `'${NPM_TOKEN}'`, in single quotes so the shell-like syntax is not
259
+ * expanded locally): the value is resolved from the check's
260
+ * environment variables on the runner, so the secret value appears
261
+ * in neither the config nor the uploaded code bundle. Any literal
262
+ * token content is rejected at config load.
263
+ *
264
+ * `packages` routes package names to upstreams, first match wins,
265
+ * top-down. Patterns use the same wildcard syntax as
266
+ * `bundle.packages.embed` (a single `*` never crosses the `/` scope
267
+ * separator, `**` does), but no `!` exclusions and no
268
+ * `name@version` pins. Each rule lists one or more upstream names
269
+ * tried in order — the first upstream that serves the package wins,
270
+ * and a 404 or unreachable upstream falls through to the next
271
+ * upstream in the same rule, never to a later rule (a broader rule
272
+ * as fallback would leak private package names to its upstreams).
273
+ * The last rule must be the match-all rule
274
+ * (`{ pattern: '**', ... }`) so every package has a route; a rule
275
+ * placed after a match-all could never apply and is rejected.
276
+ * Changing this configuration invalidates the runner's dependency
277
+ * cache.
278
+ *
279
+ * `defineConfig` type-checks that every upstream name used in
280
+ * `packages` is defined under `upstreams`; define the registries
281
+ * object inline in the config literal, since the check relies on
282
+ * type inference from the `upstreams` keys. The same rules are also
283
+ * enforced at config load for plain-JS configs.
284
+ */
285
+ registries?: Registries<UpstreamName>;
286
+ };
133
287
  /**
134
288
  * CLI default configuration properties.
135
289
  */