pepr 0.35.0 → 0.37.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 (107) hide show
  1. package/dist/cli/init/index.d.ts.map +1 -1
  2. package/dist/cli/init/templates.d.ts +3 -1
  3. package/dist/cli/init/templates.d.ts.map +1 -1
  4. package/dist/cli/init/utils.d.ts.map +1 -1
  5. package/dist/cli/init/walkthrough.d.ts +10 -3
  6. package/dist/cli/init/walkthrough.d.ts.map +1 -1
  7. package/dist/cli.js +253 -31
  8. package/dist/controller.js +138 -1
  9. package/dist/lib/adjudicators.d.ts +63 -0
  10. package/dist/lib/adjudicators.d.ts.map +1 -0
  11. package/dist/lib/adjudicators.test.d.ts +2 -0
  12. package/dist/lib/adjudicators.test.d.ts.map +1 -0
  13. package/dist/lib/assets/loader.d.ts.map +1 -1
  14. package/dist/lib/assets/pods.d.ts +1 -0
  15. package/dist/lib/assets/pods.d.ts.map +1 -1
  16. package/dist/lib/capability.d.ts +1 -0
  17. package/dist/lib/capability.d.ts.map +1 -1
  18. package/dist/lib/capability.test.d.ts +2 -0
  19. package/dist/lib/capability.test.d.ts.map +1 -0
  20. package/dist/lib/controller/index.d.ts.map +1 -1
  21. package/dist/lib/controller/store.d.ts +4 -0
  22. package/dist/lib/controller/store.d.ts.map +1 -1
  23. package/dist/lib/controller/store.test.d.ts +2 -0
  24. package/dist/lib/controller/store.test.d.ts.map +1 -0
  25. package/dist/lib/filter.d.ts +2 -3
  26. package/dist/lib/filter.d.ts.map +1 -1
  27. package/dist/lib/filter.test.d.ts +2 -1
  28. package/dist/lib/filter.test.d.ts.map +1 -1
  29. package/dist/lib/finalizer.d.ts +6 -0
  30. package/dist/lib/finalizer.d.ts.map +1 -0
  31. package/dist/lib/finalizer.test.d.ts +2 -0
  32. package/dist/lib/finalizer.test.d.ts.map +1 -0
  33. package/dist/lib/helpers.d.ts +2 -2
  34. package/dist/lib/helpers.d.ts.map +1 -1
  35. package/dist/lib/helpers.test.d.ts +1 -1
  36. package/dist/lib/helpers.test.d.ts.map +1 -1
  37. package/dist/lib/k8s.d.ts.map +1 -1
  38. package/dist/lib/logger.d.ts +1 -1
  39. package/dist/lib/logger.d.ts.map +1 -1
  40. package/dist/lib/module.d.ts +2 -1
  41. package/dist/lib/module.d.ts.map +1 -1
  42. package/dist/lib/mutate-processor.d.ts +2 -1
  43. package/dist/lib/mutate-processor.d.ts.map +1 -1
  44. package/dist/lib/mutate-request.d.ts +1 -2
  45. package/dist/lib/mutate-request.d.ts.map +1 -1
  46. package/dist/lib/queue.d.ts +19 -3
  47. package/dist/lib/queue.d.ts.map +1 -1
  48. package/dist/lib/schedule.d.ts +1 -2
  49. package/dist/lib/schedule.d.ts.map +1 -1
  50. package/dist/lib/storage.d.ts.map +1 -1
  51. package/dist/lib/types.d.ts +118 -6
  52. package/dist/lib/types.d.ts.map +1 -1
  53. package/dist/lib/validate-processor.d.ts +4 -2
  54. package/dist/lib/validate-processor.d.ts.map +1 -1
  55. package/dist/lib/validate-request.d.ts +1 -1
  56. package/dist/lib/validate-request.d.ts.map +1 -1
  57. package/dist/lib/watch-processor.d.ts +8 -6
  58. package/dist/lib/watch-processor.d.ts.map +1 -1
  59. package/dist/lib.js +467 -233
  60. package/dist/lib.js.map +4 -4
  61. package/dist/sdk/sdk.d.ts +5 -3
  62. package/dist/sdk/sdk.d.ts.map +1 -1
  63. package/package.json +13 -11
  64. package/src/cli/build.ts +3 -3
  65. package/src/cli/init/index.ts +20 -11
  66. package/src/cli/init/templates.ts +1 -1
  67. package/src/cli/init/utils.test.ts +11 -20
  68. package/src/cli/init/utils.ts +5 -0
  69. package/src/cli/init/walkthrough.test.ts +92 -11
  70. package/src/cli/init/walkthrough.ts +71 -16
  71. package/src/cli/monitor.ts +1 -1
  72. package/src/cli.ts +4 -2
  73. package/src/fixtures/data/create-pod.json +1 -1
  74. package/src/fixtures/data/delete-pod.json +1 -1
  75. package/src/lib/adjudicators.test.ts +1232 -0
  76. package/src/lib/adjudicators.ts +235 -0
  77. package/src/lib/assets/index.ts +1 -1
  78. package/src/lib/assets/loader.ts +1 -0
  79. package/src/lib/assets/webhooks.ts +1 -1
  80. package/src/lib/capability.test.ts +655 -0
  81. package/src/lib/capability.ts +112 -11
  82. package/src/lib/controller/index.ts +7 -4
  83. package/src/lib/controller/store.test.ts +131 -0
  84. package/src/lib/controller/store.ts +43 -5
  85. package/src/lib/filter.test.ts +279 -9
  86. package/src/lib/filter.ts +46 -98
  87. package/src/lib/finalizer.test.ts +236 -0
  88. package/src/lib/finalizer.ts +63 -0
  89. package/src/lib/helpers.test.ts +359 -65
  90. package/src/lib/helpers.ts +141 -95
  91. package/src/lib/k8s.ts +4 -0
  92. package/src/lib/module.ts +3 -3
  93. package/src/lib/mutate-processor.ts +5 -4
  94. package/src/lib/mutate-request.test.ts +1 -2
  95. package/src/lib/mutate-request.ts +1 -3
  96. package/src/lib/queue.test.ts +138 -44
  97. package/src/lib/queue.ts +48 -13
  98. package/src/lib/schedule.ts +1 -1
  99. package/src/lib/storage.ts +5 -6
  100. package/src/lib/types.ts +154 -5
  101. package/src/lib/validate-processor.ts +5 -2
  102. package/src/lib/validate-request.test.ts +1 -4
  103. package/src/lib/validate-request.ts +1 -1
  104. package/src/lib/watch-processor.test.ts +89 -124
  105. package/src/lib/watch-processor.ts +52 -35
  106. package/src/sdk/sdk.test.ts +46 -13
  107. package/src/sdk/sdk.ts +15 -6
package/dist/lib.js CHANGED
@@ -31,27 +31,27 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var lib_exports = {};
32
32
  __export(lib_exports, {
33
33
  Capability: () => Capability,
34
- K8s: () => import_kubernetes_fluent_client7.K8s,
34
+ K8s: () => import_kubernetes_fluent_client8.K8s,
35
35
  Log: () => logger_default,
36
36
  PeprModule: () => PeprModule,
37
37
  PeprMutateRequest: () => PeprMutateRequest,
38
38
  PeprUtils: () => utils_exports,
39
39
  PeprValidateRequest: () => PeprValidateRequest,
40
40
  R: () => R,
41
- RegisterKind: () => import_kubernetes_fluent_client7.RegisterKind,
42
- a: () => import_kubernetes_fluent_client7.kind,
43
- fetch: () => import_kubernetes_fluent_client7.fetch,
44
- fetchStatus: () => import_kubernetes_fluent_client7.fetchStatus,
45
- kind: () => import_kubernetes_fluent_client7.kind,
41
+ RegisterKind: () => import_kubernetes_fluent_client8.RegisterKind,
42
+ a: () => import_kubernetes_fluent_client8.kind,
43
+ fetch: () => import_kubernetes_fluent_client8.fetch,
44
+ fetchStatus: () => import_kubernetes_fluent_client8.fetchStatus,
45
+ kind: () => import_kubernetes_fluent_client8.kind,
46
46
  sdk: () => sdk_exports
47
47
  });
48
48
  module.exports = __toCommonJS(lib_exports);
49
- var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
49
+ var import_kubernetes_fluent_client8 = require("kubernetes-fluent-client");
50
50
  var R = __toESM(require("ramda"));
51
51
 
52
52
  // src/lib/capability.ts
53
- var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
54
- var import_ramda6 = require("ramda");
53
+ var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
54
+ var import_ramda7 = require("ramda");
55
55
 
56
56
  // src/lib/logger.ts
57
57
  var import_pino = require("pino");
@@ -74,7 +74,7 @@ if (process.env.LOG_LEVEL) {
74
74
  var logger_default = Log;
75
75
 
76
76
  // src/lib/module.ts
77
- var import_ramda4 = require("ramda");
77
+ var import_ramda5 = require("ramda");
78
78
 
79
79
  // src/lib/controller/index.ts
80
80
  var import_express = __toESM(require("express"));
@@ -224,84 +224,151 @@ function ValidateError(error = "") {
224
224
  }
225
225
  }
226
226
 
227
- // src/lib/k8s.ts
228
- var import_kubernetes_fluent_client = require("kubernetes-fluent-client");
229
- var PeprStore = class extends import_kubernetes_fluent_client.GenericKind {
230
- };
231
- var peprStoreGVK = {
232
- kind: "PeprStore",
233
- version: "v1",
234
- group: "pepr.dev"
235
- };
236
- (0, import_kubernetes_fluent_client.RegisterKind)(PeprStore, peprStoreGVK);
227
+ // src/lib/adjudicators.ts
228
+ var import_ramda = require("ramda");
229
+ var declaredOperation = (0, import_ramda.pipe)((request) => request?.operation, (0, import_ramda.defaultTo)(""));
230
+ var declaredGroup = (0, import_ramda.pipe)((request) => request?.kind?.group, (0, import_ramda.defaultTo)(""));
231
+ var declaredVersion = (0, import_ramda.pipe)((request) => request?.kind?.version, (0, import_ramda.defaultTo)(""));
232
+ var declaredKind = (0, import_ramda.pipe)((request) => request?.kind?.kind, (0, import_ramda.defaultTo)(""));
233
+ var declaredUid = (0, import_ramda.pipe)((request) => request?.uid, (0, import_ramda.defaultTo)(""));
234
+ var carriesDeletionTimestamp = (0, import_ramda.pipe)((obj) => !!obj.metadata?.deletionTimestamp, (0, import_ramda.defaultTo)(false));
235
+ var missingDeletionTimestamp = (0, import_ramda.complement)(carriesDeletionTimestamp);
236
+ var carriedName = (0, import_ramda.pipe)((obj) => obj?.metadata?.name, (0, import_ramda.defaultTo)(""));
237
+ var carriesName = (0, import_ramda.pipe)(carriedName, (0, import_ramda.equals)(""), import_ramda.not);
238
+ var missingName = (0, import_ramda.complement)(carriesName);
239
+ var carriedNamespace = (0, import_ramda.pipe)((obj) => obj?.metadata?.namespace, (0, import_ramda.defaultTo)(""));
240
+ var carriesNamespace = (0, import_ramda.pipe)(carriedNamespace, (0, import_ramda.equals)(""), import_ramda.not);
241
+ var carriedAnnotations = (0, import_ramda.pipe)((obj) => obj?.metadata?.annotations, (0, import_ramda.defaultTo)({}));
242
+ var carriesAnnotations = (0, import_ramda.pipe)(carriedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
243
+ var carriedLabels = (0, import_ramda.pipe)((obj) => obj?.metadata?.labels, (0, import_ramda.defaultTo)({}));
244
+ var carriesLabels = (0, import_ramda.pipe)(carriedLabels, (0, import_ramda.equals)({}), import_ramda.not);
245
+ var definesDeletionTimestamp = (0, import_ramda.pipe)((binding) => binding?.filters?.deletionTimestamp, (0, import_ramda.defaultTo)(false));
246
+ var ignoresDeletionTimestamp = (0, import_ramda.complement)(definesDeletionTimestamp);
247
+ var definedName = (0, import_ramda.pipe)((binding) => binding?.filters?.name, (0, import_ramda.defaultTo)(""));
248
+ var definesName = (0, import_ramda.pipe)(definedName, (0, import_ramda.equals)(""), import_ramda.not);
249
+ var ignoresName = (0, import_ramda.complement)(definesName);
250
+ var definedNameRegex = (0, import_ramda.pipe)((binding) => binding?.filters?.regexName, (0, import_ramda.defaultTo)(""));
251
+ var definesNameRegex = (0, import_ramda.pipe)(definedNameRegex, (0, import_ramda.equals)(""), import_ramda.not);
252
+ var definedNamespaces = (0, import_ramda.pipe)((binding) => binding?.filters?.namespaces, (0, import_ramda.defaultTo)([]));
253
+ var definesNamespaces = (0, import_ramda.pipe)(definedNamespaces, (0, import_ramda.equals)([]), import_ramda.not);
254
+ var definedNamespaceRegexes = (0, import_ramda.pipe)((binding) => binding?.filters?.regexNamespaces, (0, import_ramda.defaultTo)([]));
255
+ var definesNamespaceRegexes = (0, import_ramda.pipe)(definedNamespaceRegexes, (0, import_ramda.equals)([]), import_ramda.not);
256
+ var definedAnnotations = (0, import_ramda.pipe)((binding) => binding?.filters?.annotations, (0, import_ramda.defaultTo)({}));
257
+ var definesAnnotations = (0, import_ramda.pipe)(definedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
258
+ var definedLabels = (0, import_ramda.pipe)((binding) => binding?.filters?.labels, (0, import_ramda.defaultTo)({}));
259
+ var definesLabels = (0, import_ramda.pipe)(definedLabels, (0, import_ramda.equals)({}), import_ramda.not);
260
+ var definedEvent = (0, import_ramda.pipe)((binding) => binding?.event, (0, import_ramda.defaultTo)(""));
261
+ var definesDelete = (0, import_ramda.pipe)(definedEvent, (0, import_ramda.equals)("DELETE" /* DELETE */));
262
+ var definedGroup = (0, import_ramda.pipe)((binding) => binding?.kind?.group, (0, import_ramda.defaultTo)(""));
263
+ var definesGroup = (0, import_ramda.pipe)(definedGroup, (0, import_ramda.equals)(""), import_ramda.not);
264
+ var definedVersion = (0, import_ramda.pipe)((binding) => binding?.kind?.version, (0, import_ramda.defaultTo)(""));
265
+ var definesVersion = (0, import_ramda.pipe)(definedVersion, (0, import_ramda.equals)(""), import_ramda.not);
266
+ var definedKind = (0, import_ramda.pipe)((binding) => binding?.kind?.kind, (0, import_ramda.defaultTo)(""));
267
+ var definesKind = (0, import_ramda.pipe)(definedKind, (0, import_ramda.equals)(""), import_ramda.not);
268
+ var definedCategory = (0, import_ramda.pipe)((binding) => {
269
+ return binding.isFinalize ? "Finalize" : binding.isWatch ? "Watch" : binding.isMutate ? "Mutate" : binding.isValidate ? "Validate" : "";
270
+ });
271
+ var definedCallback = (0, import_ramda.pipe)((binding) => {
272
+ return binding.isFinalize ? binding.finalizeCallback : binding.isWatch ? binding.watchCallback : binding.isMutate ? binding.mutateCallback : binding.isValidate ? binding.validateCallback : null;
273
+ });
274
+ var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (cb) => cb.name);
275
+ var mismatchedDeletionTimestamp = (0, import_ramda.allPass)([
276
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesDeletionTimestamp),
277
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(1), missingDeletionTimestamp)
278
+ ]);
279
+ var mismatchedName = (0, import_ramda.allPass)([
280
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesName),
281
+ (0, import_ramda.pipe)((bnd, obj) => definedName(bnd) !== carriedName(obj))
282
+ ]);
283
+ var mismatchedNameRegex = (0, import_ramda.allPass)([
284
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNameRegex),
285
+ (0, import_ramda.pipe)((bnd, obj) => new RegExp(definedNameRegex(bnd)).test(carriedName(obj)), import_ramda.not)
286
+ ]);
287
+ var bindsToKind = (0, import_ramda.curry)(
288
+ (0, import_ramda.allPass)([(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definedKind, (0, import_ramda.equals)(""), import_ramda.not), (0, import_ramda.pipe)((bnd, knd) => definedKind(bnd) === knd)])
289
+ );
290
+ var bindsToNamespace = (0, import_ramda.curry)((0, import_ramda.pipe)(bindsToKind(import_ramda.__, "Namespace")));
291
+ var misboundNamespace = (0, import_ramda.allPass)([bindsToNamespace, definesNamespaces]);
292
+ var mismatchedNamespace = (0, import_ramda.allPass)([
293
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaces),
294
+ (0, import_ramda.pipe)((bnd, obj) => definedNamespaces(bnd).includes(carriedNamespace(obj)), import_ramda.not)
295
+ ]);
296
+ var mismatchedNamespaceRegex = (0, import_ramda.allPass)([
297
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaceRegexes),
298
+ (0, import_ramda.pipe)(
299
+ (bnd, obj) => (0, import_ramda.pipe)(
300
+ (0, import_ramda.any)((rex) => new RegExp(rex).test(carriedNamespace(obj))),
301
+ import_ramda.not
302
+ )(definedNamespaceRegexes(bnd))
303
+ )
304
+ ]);
305
+ var metasMismatch = (0, import_ramda.pipe)(
306
+ (defined, carried) => {
307
+ const result = { defined, carried, unalike: {} };
308
+ result.unalike = Object.entries(result.defined).map(([key, val]) => {
309
+ const keyMissing = !Object.hasOwn(result.carried, key);
310
+ const noValue = !val;
311
+ const valMissing = !result.carried[key];
312
+ return keyMissing ? { [key]: val } : noValue ? {} : valMissing ? { [key]: val } : {};
313
+ }).reduce((acc, cur) => ({ ...acc, ...cur }), {});
314
+ return result.unalike;
315
+ },
316
+ (unalike) => Object.keys(unalike).length > 0
317
+ );
318
+ var mismatchedAnnotations = (0, import_ramda.allPass)([
319
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesAnnotations),
320
+ (0, import_ramda.pipe)((bnd, obj) => metasMismatch(definedAnnotations(bnd), carriedAnnotations(obj)))
321
+ ]);
322
+ var mismatchedLabels = (0, import_ramda.allPass)([
323
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesLabels),
324
+ (0, import_ramda.pipe)((bnd, obj) => metasMismatch(definedLabels(bnd), carriedLabels(obj)))
325
+ ]);
326
+ var uncarryableNamespace = (0, import_ramda.allPass)([
327
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
328
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
329
+ (0, import_ramda.pipe)((nss, obj) => nss.includes(carriedNamespace(obj)), import_ramda.not)
330
+ ]);
331
+ var carriesIgnoredNamespace = (0, import_ramda.allPass)([
332
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
333
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
334
+ (0, import_ramda.pipe)((nss, obj) => nss.includes(carriedNamespace(obj)))
335
+ ]);
336
+ var unbindableNamespaces = (0, import_ramda.allPass)([
337
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
338
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(1), definesNamespaces),
339
+ (0, import_ramda.pipe)((nss, bnd) => (0, import_ramda.difference)(definedNamespaces(bnd), nss), import_ramda.length, (0, import_ramda.equals)(0), import_ramda.not)
340
+ ]);
341
+ var misboundDeleteWithDeletionTimestamp = (0, import_ramda.allPass)([definesDelete, definesDeletionTimestamp]);
342
+ var operationMatchesEvent = (0, import_ramda.anyPass)([
343
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(1), (0, import_ramda.equals)("*" /* Any */)),
344
+ (0, import_ramda.pipe)((op, evt) => op === evt),
345
+ (0, import_ramda.pipe)((op, evt) => op ? evt.includes(op) : false)
346
+ ]);
347
+ var mismatchedEvent = (0, import_ramda.pipe)(
348
+ (binding, request) => operationMatchesEvent(declaredOperation(request), definedEvent(binding)),
349
+ import_ramda.not
350
+ );
351
+ var mismatchedGroup = (0, import_ramda.allPass)([
352
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesGroup),
353
+ (0, import_ramda.pipe)((binding, request) => definedGroup(binding) !== declaredGroup(request))
354
+ ]);
355
+ var mismatchedVersion = (0, import_ramda.allPass)([
356
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesVersion),
357
+ (0, import_ramda.pipe)((binding, request) => definedVersion(binding) !== declaredVersion(request))
358
+ ]);
359
+ var mismatchedKind = (0, import_ramda.allPass)([
360
+ (0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesKind),
361
+ (0, import_ramda.pipe)((binding, request) => definedKind(binding) !== declaredKind(request))
362
+ ]);
237
363
 
238
364
  // src/lib/filter.ts
239
- function shouldSkipRequest(binding, req, capabilityNamespaces) {
240
- const { group, kind: kind4, version } = binding.kind || {};
241
- const { namespaces, labels, annotations, name } = binding.filters || {};
242
- const operation = req.operation.toUpperCase();
243
- const uid = req.uid;
244
- const srcObject = operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
245
- const { metadata } = srcObject || {};
246
- const combinedNamespaces = [...namespaces, ...capabilityNamespaces];
247
- if (!binding.event.includes(operation) && !binding.event.includes("*" /* Any */)) {
248
- return true;
249
- }
250
- if (name && name !== req.name) {
251
- return true;
252
- }
253
- if (kind4 !== req.kind.kind) {
254
- return true;
255
- }
256
- if (group && group !== req.kind.group) {
257
- return true;
258
- }
259
- if (version && version !== req.kind.version) {
260
- return true;
261
- }
262
- if (combinedNamespaces.length && !combinedNamespaces.includes(req.namespace || "") || !namespaces.includes(req.namespace || "") && capabilityNamespaces.length !== 0 && namespaces.length !== 0) {
263
- let type = "";
264
- let label = "";
265
- if (binding.isMutate) {
266
- type = "Mutate";
267
- label = binding.mutateCallback.name;
268
- } else if (binding.isValidate) {
269
- type = "Validate";
270
- label = binding.validateCallback.name;
271
- } else if (binding.isWatch) {
272
- type = "Watch";
273
- label = binding.watchCallback.name;
274
- }
275
- logger_default.debug({ uid }, `${type} binding (${label}) does not match request namespace "${req.namespace}"`);
276
- return true;
277
- }
278
- for (const [key, value] of Object.entries(labels)) {
279
- const testKey = metadata?.labels?.[key];
280
- if (!testKey) {
281
- logger_default.debug({ uid }, `Label ${key} does not exist`);
282
- return true;
283
- }
284
- if (value && testKey !== value) {
285
- logger_default.debug({ uid }, `${testKey} does not match ${value}`);
286
- return true;
287
- }
288
- }
289
- for (const [key, value] of Object.entries(annotations)) {
290
- const testKey = metadata?.annotations?.[key];
291
- if (!testKey) {
292
- logger_default.debug({ uid }, `Annotation ${key} does not exist`);
293
- return true;
294
- }
295
- if (value && testKey !== value) {
296
- logger_default.debug({ uid }, `${testKey} does not match ${value}`);
297
- return true;
298
- }
299
- }
300
- return false;
365
+ function shouldSkipRequest(binding, req, capabilityNamespaces, ignoredNamespaces) {
366
+ const obj = req.operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
367
+ return misboundDeleteWithDeletionTimestamp(binding) ? true : mismatchedDeletionTimestamp(binding, obj) ? true : mismatchedEvent(binding, req) ? true : mismatchedName(binding, obj) ? true : mismatchedGroup(binding, req) ? true : mismatchedVersion(binding, req) ? true : mismatchedKind(binding, req) ? true : unbindableNamespaces(capabilityNamespaces, binding) ? true : uncarryableNamespace(capabilityNamespaces, obj) ? true : mismatchedNamespace(binding, obj) ? true : mismatchedLabels(binding, obj) ? true : mismatchedAnnotations(binding, obj) ? true : mismatchedNamespaceRegex(binding, obj) ? true : mismatchedNameRegex(binding, obj) ? true : carriesIgnoredNamespace(ignoredNamespaces, obj) ? true : false;
301
368
  }
302
369
 
303
370
  // src/lib/mutate-request.ts
304
- var import_ramda = require("ramda");
371
+ var import_ramda2 = require("ramda");
305
372
  var PeprMutateRequest = class {
306
373
  Raw;
307
374
  #input;
@@ -336,9 +403,9 @@ var PeprMutateRequest = class {
336
403
  constructor(input) {
337
404
  this.#input = input;
338
405
  if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
339
- this.Raw = (0, import_ramda.clone)(input.oldObject);
406
+ this.Raw = (0, import_ramda2.clone)(input.oldObject);
340
407
  } else {
341
- this.Raw = (0, import_ramda.clone)(input.object);
408
+ this.Raw = (0, import_ramda2.clone)(input.object);
342
409
  }
343
410
  if (!this.Raw) {
344
411
  throw new Error("unable to load the request object into PeprRequest.RawP");
@@ -350,7 +417,7 @@ var PeprMutateRequest = class {
350
417
  * @param obj - The object to merge with the current resource.
351
418
  */
352
419
  Merge = (obj) => {
353
- this.Raw = (0, import_ramda.mergeDeepRight)(this.Raw, obj);
420
+ this.Raw = (0, import_ramda2.mergeDeepRight)(this.Raw, obj);
354
421
  };
355
422
  /**
356
423
  * Updates a label on the Kubernetes resource.
@@ -483,7 +550,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
483
550
  if (!action.mutateCallback) {
484
551
  continue;
485
552
  }
486
- if (shouldSkipRequest(action, req, namespaces)) {
553
+ if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
487
554
  continue;
488
555
  }
489
556
  const label = action.mutateCallback.name;
@@ -556,7 +623,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
556
623
  }
557
624
 
558
625
  // src/lib/validate-request.ts
559
- var import_ramda2 = require("ramda");
626
+ var import_ramda3 = require("ramda");
560
627
  var PeprValidateRequest = class {
561
628
  Raw;
562
629
  #input;
@@ -581,9 +648,9 @@ var PeprValidateRequest = class {
581
648
  constructor(input) {
582
649
  this.#input = input;
583
650
  if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
584
- this.Raw = (0, import_ramda2.clone)(input.oldObject);
651
+ this.Raw = (0, import_ramda3.clone)(input.oldObject);
585
652
  } else {
586
- this.Raw = (0, import_ramda2.clone)(input.object);
653
+ this.Raw = (0, import_ramda3.clone)(input.object);
587
654
  }
588
655
  if (!this.Raw) {
589
656
  throw new Error("unable to load the request object into PeprRequest.Raw");
@@ -634,7 +701,7 @@ var PeprValidateRequest = class {
634
701
  };
635
702
 
636
703
  // src/lib/validate-processor.ts
637
- async function validateProcessor(capabilities, req, reqMetadata) {
704
+ async function validateProcessor(config, capabilities, req, reqMetadata) {
638
705
  const wrapped = new PeprValidateRequest(req);
639
706
  const response = [];
640
707
  const isSecret = req.kind.version == "v1" && req.kind.kind == "Secret";
@@ -653,7 +720,7 @@ async function validateProcessor(capabilities, req, reqMetadata) {
653
720
  allowed: true
654
721
  // Assume it's allowed until a validation check fails
655
722
  };
656
- if (shouldSkipRequest(action, req, namespaces)) {
723
+ if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
657
724
  continue;
658
725
  }
659
726
  const label = action.validateCallback.name;
@@ -685,7 +752,21 @@ async function validateProcessor(capabilities, req, reqMetadata) {
685
752
 
686
753
  // src/lib/controller/store.ts
687
754
  var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
688
- var import_ramda3 = require("ramda");
755
+ var import_ramda4 = require("ramda");
756
+
757
+ // src/lib/k8s.ts
758
+ var import_kubernetes_fluent_client = require("kubernetes-fluent-client");
759
+ var PeprStore = class extends import_kubernetes_fluent_client.GenericKind {
760
+ };
761
+ var peprStoreGVK = {
762
+ kind: "PeprStore",
763
+ version: "v1",
764
+ group: "pepr.dev"
765
+ };
766
+ (0, import_kubernetes_fluent_client.RegisterKind)(PeprStore, peprStoreGVK);
767
+
768
+ // src/lib/controller/store.ts
769
+ var redactedValue = "**redacted**";
689
770
  var namespace = "pepr-system";
690
771
  var debounceBackoff = 5e3;
691
772
  var PeprControllerStore = class {
@@ -722,7 +803,7 @@ var PeprControllerStore = class {
722
803
  watcher.start().catch((e) => logger_default.error(e, "Error starting Pepr store watch"));
723
804
  };
724
805
  #migrateAndSetupWatch = async (store) => {
725
- logger_default.debug(store, "Pepr Store migration");
806
+ logger_default.debug(redactedStore(store), "Pepr Store migration");
726
807
  const data = store.data || {};
727
808
  const migrateCache = {};
728
809
  const flushCache = async () => {
@@ -732,7 +813,9 @@ var PeprControllerStore = class {
732
813
  delete migrateCache[idx];
733
814
  }
734
815
  try {
735
- await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
816
+ if (payload.length > 0) {
817
+ await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
818
+ }
736
819
  } catch (err) {
737
820
  logger_default.error(err, "Pepr store update failure");
738
821
  if (err.status === 422) {
@@ -768,7 +851,7 @@ var PeprControllerStore = class {
768
851
  for (const name of Object.keys(this.#stores)) {
769
852
  const offset = `${name}-`.length;
770
853
  for (const key of Object.keys(data)) {
771
- if ((0, import_ramda3.startsWith)(name, key) && !(0, import_ramda3.startsWith)(`${name}-v2`, key)) {
854
+ if ((0, import_ramda4.startsWith)(name, key) && !(0, import_ramda4.startsWith)(`${name}-v2`, key)) {
772
855
  fillCache(name, "remove", [key.slice(offset)], data[key]);
773
856
  fillCache(name, "add", [key.slice(offset)], data[key]);
774
857
  }
@@ -778,14 +861,14 @@ var PeprControllerStore = class {
778
861
  this.#setupWatch();
779
862
  };
780
863
  #receive = (store) => {
781
- logger_default.debug(store, "Pepr Store update");
864
+ logger_default.debug(redactedStore(store), "Pepr Store update");
782
865
  const debounced = () => {
783
866
  const data = store.data || {};
784
867
  for (const name of Object.keys(this.#stores)) {
785
868
  const offset = `${name}-`.length;
786
869
  const filtered = {};
787
870
  for (const key of Object.keys(data)) {
788
- if ((0, import_ramda3.startsWith)(name, key)) {
871
+ if ((0, import_ramda4.startsWith)(name, key)) {
789
872
  filtered[key.slice(offset)] = data[key];
790
873
  }
791
874
  }
@@ -829,7 +912,9 @@ var PeprControllerStore = class {
829
912
  delete sendCache[idx];
830
913
  }
831
914
  try {
832
- await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
915
+ if (payload.length > 0) {
916
+ await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
917
+ }
833
918
  } catch (err) {
834
919
  logger_default.error(err, "Pepr store update failure");
835
920
  if (err.status === 422) {
@@ -846,7 +931,7 @@ var PeprControllerStore = class {
846
931
  };
847
932
  setInterval(() => {
848
933
  if (Object.keys(sendCache).length > 0) {
849
- logger_default.debug(sendCache, "Sending updates to Pepr store");
934
+ logger_default.debug(redactedPatch(sendCache), "Sending updates to Pepr store");
850
935
  void flushCache();
851
936
  }
852
937
  }, debounceBackoff);
@@ -872,8 +957,38 @@ var PeprControllerStore = class {
872
957
  }
873
958
  };
874
959
  };
960
+ function redactedStore(store) {
961
+ const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
962
+ return {
963
+ ...store,
964
+ data: Object.keys(store.data).reduce((acc, key) => {
965
+ acc[key] = redacted ? redactedValue : store.data[key];
966
+ return acc;
967
+ }, {})
968
+ };
969
+ }
970
+ function redactedPatch(patch = {}) {
971
+ const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
972
+ if (!redacted) {
973
+ return patch;
974
+ }
975
+ const redactedCache = {};
976
+ Object.keys(patch).forEach((key) => {
977
+ const operation = patch[key];
978
+ const redactedKey = key.includes(":") ? key.substring(0, key.lastIndexOf(":")) + ":**redacted**" : key;
979
+ const redactedOperation = {
980
+ ...operation,
981
+ ..."value" in operation ? { value: "**redacted**" } : {}
982
+ };
983
+ redactedCache[redactedKey] = redactedOperation;
984
+ });
985
+ return redactedCache;
986
+ }
875
987
 
876
988
  // src/lib/controller/index.ts
989
+ if (!process.env.PEPR_NODE_WARNINGS) {
990
+ process.removeAllListeners("warning");
991
+ }
877
992
  var Controller = class _Controller {
878
993
  // Track whether the server is running
879
994
  #running = false;
@@ -933,7 +1048,7 @@ var Controller = class _Controller {
933
1048
  });
934
1049
  server.on("error", (e) => {
935
1050
  if (e.code === "EADDRINUSE") {
936
- logger_default.warn(
1051
+ logger_default.info(
937
1052
  `Address in use, retrying in 2 seconds. If this persists, ensure ${port} is not in use, e.g. "lsof -i :${port}"`
938
1053
  );
939
1054
  setTimeout(() => {
@@ -972,7 +1087,7 @@ var Controller = class _Controller {
972
1087
  const { token } = req.params;
973
1088
  if (token !== this.#token) {
974
1089
  const err = `Unauthorized: invalid token '${token.replace(/[^\w]/g, "_")}'`;
975
- logger_default.warn(err);
1090
+ logger_default.info(err);
976
1091
  res.status(401).send(err);
977
1092
  this.#metricsCollector.alert();
978
1093
  return;
@@ -1019,7 +1134,7 @@ var Controller = class _Controller {
1019
1134
  if (admissionKind === "Mutate") {
1020
1135
  response = await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata);
1021
1136
  } else {
1022
- response = await validateProcessor(this.#capabilities, request, reqMetadata);
1137
+ response = await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);
1023
1138
  }
1024
1139
  const responseList = Array.isArray(response) ? response : [response];
1025
1140
  responseList.map((res2) => {
@@ -1080,7 +1195,7 @@ var Controller = class _Controller {
1080
1195
  status: res.statusCode,
1081
1196
  duration: `${elapsedTime} ms`
1082
1197
  };
1083
- res.statusCode >= 300 ? logger_default.warn(message) : logger_default.info(message);
1198
+ logger_default.info(message);
1084
1199
  });
1085
1200
  next();
1086
1201
  }
@@ -1101,8 +1216,8 @@ var Controller = class _Controller {
1101
1216
  };
1102
1217
 
1103
1218
  // src/lib/watch-processor.ts
1104
- var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
1105
- var import_types2 = require("kubernetes-fluent-client/dist/fluent/types");
1219
+ var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
1220
+ var import_types6 = require("kubernetes-fluent-client/dist/fluent/types");
1106
1221
 
1107
1222
  // src/lib/helpers.ts
1108
1223
  var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
@@ -1154,14 +1269,17 @@ async function writeEvent(cr, event, eventType, eventReason, reportingComponent,
1154
1269
  reportingInstance
1155
1270
  });
1156
1271
  }
1157
- function getOwnerRefFrom(cr) {
1158
- const { name, uid } = cr.metadata;
1272
+ function getOwnerRefFrom(customResource, blockOwnerDeletion, controller) {
1273
+ const { apiVersion, kind: kind4, metadata } = customResource;
1274
+ const { name, uid } = metadata;
1159
1275
  return [
1160
1276
  {
1161
- apiVersion: cr.apiVersion,
1162
- kind: cr.kind,
1277
+ apiVersion,
1278
+ kind: kind4,
1163
1279
  uid,
1164
- name
1280
+ name,
1281
+ ...blockOwnerDeletion !== void 0 && { blockOwnerDeletion },
1282
+ ...controller !== void 0 && { controller }
1165
1283
  }
1166
1284
  ];
1167
1285
  }
@@ -1170,80 +1288,97 @@ function sanitizeResourceName(name) {
1170
1288
  }
1171
1289
 
1172
1290
  // src/lib/helpers.ts
1173
- function checkOverlap(bindingFilters, objectFilters) {
1174
- if (Object.keys(bindingFilters).length === 0) {
1175
- return true;
1176
- }
1177
- let matchCount = 0;
1178
- for (const key in bindingFilters) {
1179
- if (Object.prototype.hasOwnProperty.call(objectFilters, key)) {
1180
- const val1 = bindingFilters[key];
1181
- const val2 = objectFilters[key];
1182
- if (val1 === "" && key in objectFilters) {
1183
- matchCount++;
1184
- } else if (val1 !== "" && val1 === val2) {
1185
- matchCount++;
1186
- }
1187
- }
1188
- }
1189
- return matchCount === Object.keys(bindingFilters).length;
1291
+ function filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespaces) {
1292
+ const prefix = "Ignoring Watch Callback:";
1293
+ return mismatchedDeletionTimestamp(binding, obj) ? `${prefix} Binding defines deletionTimestamp but Object does not carry it.` : mismatchedName(binding, obj) ? `${prefix} Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.` : misboundNamespace(binding) ? `${prefix} Cannot use namespace filter on a namespace object.` : mismatchedLabels(binding, obj) ? `${prefix} Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.` : mismatchedAnnotations(binding, obj) ? `${prefix} Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.` : uncarryableNamespace(capabilityNamespaces, obj) ? `${prefix} Object carries namespace '${carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : unbindableNamespaces(capabilityNamespaces, binding) ? `${prefix} Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : mismatchedNamespace(binding, obj) ? `${prefix} Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.` : mismatchedNamespaceRegex(binding, obj) ? `${prefix} Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.` : mismatchedNameRegex(binding, obj) ? `${prefix} Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.` : carriesIgnoredNamespace(ignoredNamespaces, obj) ? `${prefix} Object carries namespace '${carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.` : "";
1190
1294
  }
1191
- function filterNoMatchReason(binding, obj, capabilityNamespaces) {
1192
- if (binding.kind && binding.kind.kind === "Namespace" && binding.filters && binding.filters.namespaces.length !== 0) {
1193
- return `Ignoring Watch Callback: Cannot use a namespace filter in a namespace object.`;
1194
- }
1195
- if (typeof obj === "object" && obj !== null && "metadata" in obj && obj.metadata !== void 0 && binding.filters) {
1196
- if (obj.metadata.labels && !checkOverlap(binding.filters.labels, obj.metadata.labels)) {
1197
- return `Ignoring Watch Callback: No overlap between binding and object labels. Binding labels ${JSON.stringify(
1198
- binding.filters.labels
1199
- )}, Object Labels ${JSON.stringify(obj.metadata.labels)}.`;
1200
- }
1201
- if (obj.metadata.annotations && !checkOverlap(binding.filters.annotations, obj.metadata.annotations)) {
1202
- return `Ignoring Watch Callback: No overlap between binding and object annotations. Binding annotations ${JSON.stringify(
1203
- binding.filters.annotations
1204
- )}, Object annotations ${JSON.stringify(obj.metadata.annotations)}.`;
1205
- }
1295
+
1296
+ // src/lib/finalizer.ts
1297
+ var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
1298
+ function addFinalizer(request) {
1299
+ if (request.Request.operation === "DELETE" /* DELETE */) {
1300
+ return;
1206
1301
  }
1207
- if (Array.isArray(capabilityNamespaces) && capabilityNamespaces.length > 0 && obj.metadata && obj.metadata.namespace && !capabilityNamespaces.includes(obj.metadata.namespace)) {
1208
- return `Ignoring Watch Callback: Object is not in the capability namespace. Capability namespaces: ${capabilityNamespaces.join(
1209
- ", "
1210
- )}, Object namespace: ${obj.metadata.namespace}.`;
1302
+ if (request.Request.operation === "UPDATE" /* UPDATE */ && request.Raw.metadata?.deletionTimestamp) {
1303
+ return;
1211
1304
  }
1212
- if (Array.isArray(capabilityNamespaces) && capabilityNamespaces.length > 0 && binding.filters && Array.isArray(binding.filters.namespaces) && binding.filters.namespaces.length > 0 && !binding.filters.namespaces.every((ns) => capabilityNamespaces.includes(ns))) {
1213
- return `Ignoring Watch Callback: Binding namespace is not part of capability namespaces. Capability namespaces: ${capabilityNamespaces.join(
1214
- ", "
1215
- )}, Binding namespaces: ${binding.filters.namespaces.join(", ")}.`;
1305
+ const peprFinal = "pepr.dev/finalizer";
1306
+ const finalizers = request.Raw.metadata?.finalizers || [];
1307
+ if (!finalizers.includes(peprFinal)) {
1308
+ finalizers.push(peprFinal);
1216
1309
  }
1217
- if (binding.filters && Array.isArray(binding.filters.namespaces) && binding.filters.namespaces.length > 0 && obj.metadata && obj.metadata.namespace && !binding.filters.namespaces.includes(obj.metadata.namespace)) {
1218
- return `Ignoring Watch Callback: Binding namespace and object namespace are not the same. Binding namespaces: ${binding.filters.namespaces.join(
1219
- ", "
1220
- )}, Object namespace: ${obj.metadata.namespace}.`;
1310
+ request.Merge({ metadata: { finalizers } });
1311
+ }
1312
+ async function removeFinalizer(binding, obj) {
1313
+ const peprFinal = "pepr.dev/finalizer";
1314
+ const meta = obj.metadata;
1315
+ const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
1316
+ logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
1317
+ const { model, kind: kind4 } = binding;
1318
+ try {
1319
+ (0, import_kubernetes_fluent_client5.RegisterKind)(model, kind4);
1320
+ } catch (e) {
1321
+ const expected = e.message === `GVK ${model.name} already registered`;
1322
+ if (!expected) {
1323
+ logger_default.error({ model, kind: kind4, error: e }, `Error registering "${kind4}" during finalization.`);
1324
+ return;
1325
+ }
1221
1326
  }
1222
- return "";
1327
+ const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
1328
+ obj = await (0, import_kubernetes_fluent_client5.K8s)(model, meta).Patch([
1329
+ {
1330
+ op: "replace",
1331
+ path: `/metadata/finalizers`,
1332
+ value: finalizers
1333
+ }
1334
+ ]);
1335
+ logger_default.debug({ obj }, `Removed finalizer '${peprFinal}' from '${resource}'`);
1223
1336
  }
1224
1337
 
1225
1338
  // src/lib/queue.ts
1339
+ var import_node_crypto = require("node:crypto");
1226
1340
  var Queue = class {
1341
+ #name;
1342
+ #uid;
1227
1343
  #queue = [];
1228
1344
  #pendingPromise = false;
1229
- #reconcile;
1230
- constructor() {
1231
- this.#reconcile = async () => await new Promise((resolve) => resolve());
1345
+ constructor(name) {
1346
+ this.#name = name;
1347
+ this.#uid = `${Date.now()}-${(0, import_node_crypto.randomBytes)(2).toString("hex")}`;
1232
1348
  }
1233
- setReconcile(reconcile) {
1234
- this.#reconcile = reconcile;
1349
+ label() {
1350
+ return { name: this.#name, uid: this.#uid };
1351
+ }
1352
+ stats() {
1353
+ return {
1354
+ queue: this.label(),
1355
+ stats: {
1356
+ length: this.#queue.length
1357
+ }
1358
+ };
1235
1359
  }
1236
1360
  /**
1237
1361
  * Enqueue adds an item to the queue and returns a promise that resolves when the item is
1238
1362
  * reconciled.
1239
1363
  *
1240
1364
  * @param item The object to reconcile
1365
+ * @param type The watch phase requested for reconcile
1366
+ * @param reconcile The callback to enqueue for reconcile
1241
1367
  * @returns A promise that resolves when the object is reconciled
1242
1368
  */
1243
- enqueue(item, type) {
1244
- logger_default.debug(`Enqueueing ${item.metadata.namespace}/${item.metadata.name}`);
1369
+ enqueue(item, phase, reconcile) {
1370
+ const note = {
1371
+ queue: this.label(),
1372
+ item: {
1373
+ name: item.metadata?.name,
1374
+ namespace: item.metadata?.namespace,
1375
+ resourceVersion: item.metadata?.resourceVersion
1376
+ }
1377
+ };
1378
+ logger_default.debug(note, "Enqueueing");
1245
1379
  return new Promise((resolve, reject) => {
1246
- this.#queue.push({ item, type, resolve, reject });
1380
+ this.#queue.push({ item, phase, callback: reconcile, resolve, reject });
1381
+ logger_default.debug(this.stats(), "Queue stats - push");
1247
1382
  return this.#dequeue();
1248
1383
  });
1249
1384
  }
@@ -1264,15 +1399,23 @@ var Queue = class {
1264
1399
  }
1265
1400
  try {
1266
1401
  this.#pendingPromise = true;
1267
- if (this.#reconcile) {
1268
- logger_default.debug(`Reconciling ${element.item.metadata.name}`);
1269
- await this.#reconcile(element.item, element.type);
1270
- }
1402
+ const note = {
1403
+ queue: this.label(),
1404
+ item: {
1405
+ name: element.item.metadata?.name,
1406
+ namespace: element.item.metadata?.namespace,
1407
+ resourceVersion: element.item.metadata?.resourceVersion
1408
+ }
1409
+ };
1410
+ logger_default.debug(note, "Reconciling");
1411
+ await element.callback(element.item, element.phase);
1412
+ logger_default.debug(note, "Reconciled");
1271
1413
  element.resolve();
1272
1414
  } catch (e) {
1273
1415
  logger_default.debug(`Error reconciling ${element.item.metadata.name}`, { error: e });
1274
1416
  element.reject(e);
1275
1417
  } finally {
1418
+ logger_default.debug(this.stats(), "Queue stats - shift");
1276
1419
  logger_default.debug("Resetting pending promise and dequeuing");
1277
1420
  this.#pendingPromise = false;
1278
1421
  await this.#dequeue();
@@ -1281,16 +1424,29 @@ var Queue = class {
1281
1424
  };
1282
1425
 
1283
1426
  // src/lib/watch-processor.ts
1284
- var queueRecord = {};
1285
- function queueRecordKey(obj) {
1286
- const options = ["singular", "sharded"];
1287
- const d3fault = "singular";
1427
+ var queues = {};
1428
+ function queueKey(obj) {
1429
+ const options = ["kind", "kindNs", "kindNsName", "global"];
1430
+ const d3fault = "kind";
1288
1431
  let strat = process.env.PEPR_RECONCILE_STRATEGY || d3fault;
1289
1432
  strat = options.includes(strat) ? strat : d3fault;
1290
1433
  const ns = obj.metadata?.namespace ?? "cluster-scoped";
1291
1434
  const kind4 = obj.kind ?? "UnknownKind";
1292
1435
  const name = obj.metadata?.name ?? "Unnamed";
1293
- return strat === "singular" ? `${kind4}/${ns}` : `${kind4}/${name}/${ns}`;
1436
+ const lookup = {
1437
+ kind: `${kind4}`,
1438
+ kindNs: `${kind4}/${ns}`,
1439
+ kindNsName: `${kind4}/${ns}/${name}`,
1440
+ global: "global"
1441
+ };
1442
+ return lookup[strat];
1443
+ }
1444
+ function getOrCreateQueue(obj) {
1445
+ const key = queueKey(obj);
1446
+ if (!queues[key]) {
1447
+ queues[key] = new Queue(key);
1448
+ }
1449
+ return queues[key];
1294
1450
  }
1295
1451
  var watchCfg = {
1296
1452
  resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10) : 5,
@@ -1299,26 +1455,37 @@ var watchCfg = {
1299
1455
  relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10) : 600
1300
1456
  };
1301
1457
  var eventToPhaseMap = {
1302
- ["CREATE" /* Create */]: [import_types2.WatchPhase.Added],
1303
- ["UPDATE" /* Update */]: [import_types2.WatchPhase.Modified],
1304
- ["CREATEORUPDATE" /* CreateOrUpdate */]: [import_types2.WatchPhase.Added, import_types2.WatchPhase.Modified],
1305
- ["DELETE" /* Delete */]: [import_types2.WatchPhase.Deleted],
1306
- ["*" /* Any */]: [import_types2.WatchPhase.Added, import_types2.WatchPhase.Modified, import_types2.WatchPhase.Deleted]
1458
+ ["CREATE" /* Create */]: [import_types6.WatchPhase.Added],
1459
+ ["UPDATE" /* Update */]: [import_types6.WatchPhase.Modified],
1460
+ ["CREATEORUPDATE" /* CreateOrUpdate */]: [import_types6.WatchPhase.Added, import_types6.WatchPhase.Modified],
1461
+ ["DELETE" /* Delete */]: [import_types6.WatchPhase.Deleted],
1462
+ ["*" /* Any */]: [import_types6.WatchPhase.Added, import_types6.WatchPhase.Modified, import_types6.WatchPhase.Deleted]
1307
1463
  };
1308
- function setupWatch(capabilities) {
1464
+ function setupWatch(capabilities, ignoredNamespaces) {
1309
1465
  capabilities.map(
1310
- (capability) => capability.bindings.filter((binding) => binding.isWatch).forEach((bindingElement) => runBinding(bindingElement, capability.namespaces))
1466
+ (capability) => capability.bindings.filter((binding) => binding.isWatch).forEach((bindingElement) => runBinding(bindingElement, capability.namespaces, ignoredNamespaces))
1311
1467
  );
1312
1468
  }
1313
- async function runBinding(binding, capabilityNamespaces) {
1469
+ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
1314
1470
  const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /* Any */];
1315
1471
  logger_default.debug({ watchCfg }, "Effective WatchConfig");
1316
- const watchCallback = async (obj, type) => {
1317
- if (phaseMatch.includes(type)) {
1472
+ const watchCallback = async (obj, phase) => {
1473
+ if (phaseMatch.includes(phase)) {
1318
1474
  try {
1319
- const filterMatch = filterNoMatchReason(binding, obj, capabilityNamespaces);
1475
+ const filterMatch = filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespaces);
1320
1476
  if (filterMatch === "") {
1321
- await binding.watchCallback?.(obj, type);
1477
+ if (binding.isFinalize) {
1478
+ if (!obj.metadata?.deletionTimestamp) {
1479
+ return;
1480
+ }
1481
+ try {
1482
+ await binding.finalizeCallback?.(obj);
1483
+ } finally {
1484
+ await removeFinalizer(binding, obj);
1485
+ }
1486
+ } else {
1487
+ await binding.watchCallback?.(obj, phase);
1488
+ }
1322
1489
  } else {
1323
1490
  logger_default.debug(filterMatch);
1324
1491
  }
@@ -1327,46 +1494,39 @@ async function runBinding(binding, capabilityNamespaces) {
1327
1494
  }
1328
1495
  }
1329
1496
  };
1330
- function getOrCreateQueue(key) {
1331
- if (!queueRecord[key]) {
1332
- queueRecord[key] = new Queue();
1333
- queueRecord[key].setReconcile(watchCallback);
1334
- }
1335
- return queueRecord[key];
1336
- }
1337
- const watcher = (0, import_kubernetes_fluent_client5.K8s)(binding.model, binding.filters).Watch(async (obj, type) => {
1338
- logger_default.debug(obj, `Watch event ${type} received`);
1339
- const queue = getOrCreateQueue(queueRecordKey(obj));
1497
+ const watcher = (0, import_kubernetes_fluent_client6.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
1498
+ logger_default.debug(obj, `Watch event ${phase} received`);
1340
1499
  if (binding.isQueue) {
1341
- await queue.enqueue(obj, type);
1500
+ const queue = getOrCreateQueue(obj);
1501
+ await queue.enqueue(obj, phase, watchCallback);
1342
1502
  } else {
1343
- await watchCallback(obj, type);
1503
+ await watchCallback(obj, phase);
1344
1504
  }
1345
1505
  }, watchCfg);
1346
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.GIVE_UP, (err) => {
1506
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => {
1347
1507
  logger_default.error(err, "Watch failed after 5 attempts, giving up");
1348
1508
  process.exit(1);
1349
1509
  });
1350
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client5.WatchEvent.CONNECT, url));
1351
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.DATA_ERROR, err.message));
1510
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client6.WatchEvent.CONNECT, url));
1511
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.DATA_ERROR, err.message));
1352
1512
  watcher.events.on(
1353
- import_kubernetes_fluent_client5.WatchEvent.RECONNECT,
1354
- (retryCount) => logEvent(import_kubernetes_fluent_client5.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
1513
+ import_kubernetes_fluent_client6.WatchEvent.RECONNECT,
1514
+ (retryCount) => logEvent(import_kubernetes_fluent_client6.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
1355
1515
  );
1356
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client5.WatchEvent.RECONNECT_PENDING));
1357
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.GIVE_UP, err.message));
1358
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.ABORT, err.message));
1359
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.OLD_RESOURCE_VERSION, err));
1360
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.NETWORK_ERROR, err.message));
1361
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.LIST_ERROR, err.message));
1362
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client5.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
1363
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.CACHE_MISS, (windowName) => {
1516
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client6.WatchEvent.RECONNECT_PENDING));
1517
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, err.message));
1518
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.ABORT, err.message));
1519
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.OLD_RESOURCE_VERSION, err));
1520
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.NETWORK_ERROR, err.message));
1521
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.LIST_ERROR, err.message));
1522
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client6.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
1523
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.CACHE_MISS, (windowName) => {
1364
1524
  metricsCollector.incCacheMiss(windowName);
1365
1525
  });
1366
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.INIT_CACHE_MISS, (windowName) => {
1526
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INIT_CACHE_MISS, (windowName) => {
1367
1527
  metricsCollector.initCacheMissWindow(windowName);
1368
1528
  });
1369
- watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
1529
+ watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
1370
1530
  metricsCollector.incRetryCount(retryCount);
1371
1531
  });
1372
1532
  try {
@@ -1376,8 +1536,8 @@ async function runBinding(binding, capabilityNamespaces) {
1376
1536
  process.exit(1);
1377
1537
  }
1378
1538
  }
1379
- function logEvent(type, message = "", obj) {
1380
- const logMessage = `Watch event ${type} received${message ? `. ${message}.` : "."}`;
1539
+ function logEvent(event, message = "", obj) {
1540
+ const logMessage = `Watch event ${event} received${message ? `. ${message}.` : "."}`;
1381
1541
  if (obj) {
1382
1542
  logger_default.debug(obj, logMessage);
1383
1543
  } else {
@@ -1399,7 +1559,7 @@ var PeprModule = class {
1399
1559
  * @param opts Options for the Pepr runtime
1400
1560
  */
1401
1561
  constructor({ description, pepr }, capabilities = [], opts = {}) {
1402
- const config = (0, import_ramda4.clone)(pepr);
1562
+ const config = (0, import_ramda5.clone)(pepr);
1403
1563
  config.description = description;
1404
1564
  ValidateError(config.onError);
1405
1565
  if (isBuildMode()) {
@@ -1422,7 +1582,7 @@ var PeprModule = class {
1422
1582
  this.#controller = new Controller(config, capabilities, opts.beforeHook, opts.afterHook, () => {
1423
1583
  if (isWatchMode() || isDevMode()) {
1424
1584
  try {
1425
- setupWatch(capabilities);
1585
+ setupWatch(capabilities, pepr?.alwaysIgnore?.namespaces);
1426
1586
  } catch (e) {
1427
1587
  logger_default.error(e, "Error setting up watch");
1428
1588
  process.exit(1);
@@ -1446,7 +1606,7 @@ var PeprModule = class {
1446
1606
  };
1447
1607
 
1448
1608
  // src/lib/storage.ts
1449
- var import_ramda5 = require("ramda");
1609
+ var import_ramda6 = require("ramda");
1450
1610
  var import_json_pointer = __toESM(require("json-pointer"));
1451
1611
  var MAX_WAIT_TIME = 15e3;
1452
1612
  var STORE_VERSION_PREFIX = "v2";
@@ -1466,11 +1626,10 @@ var Storage = class {
1466
1626
  this.#send = send;
1467
1627
  };
1468
1628
  receive = (data) => {
1469
- logger_default.debug(data, `Pepr store data received`);
1470
1629
  this.#store = data || {};
1471
1630
  this.#onReady();
1472
1631
  for (const idx in this.#subscribers) {
1473
- this.#subscribers[idx]((0, import_ramda5.clone)(this.#store));
1632
+ this.#subscribers[idx]((0, import_ramda6.clone)(this.#store));
1474
1633
  }
1475
1634
  };
1476
1635
  getItem = (key) => {
@@ -1481,7 +1640,7 @@ var Storage = class {
1481
1640
  return null;
1482
1641
  };
1483
1642
  clear = () => {
1484
- this.#dispatchUpdate(
1643
+ Object.keys(this.#store).length > 0 && this.#dispatchUpdate(
1485
1644
  "remove",
1486
1645
  Object.keys(this.#store).map((key) => import_json_pointer.default.escape(key))
1487
1646
  );
@@ -1554,7 +1713,7 @@ var Storage = class {
1554
1713
  };
1555
1714
  #onReady = () => {
1556
1715
  for (const handler of this.#readyHandlers) {
1557
- handler((0, import_ramda5.clone)(this.#store));
1716
+ handler((0, import_ramda6.clone)(this.#store));
1558
1717
  }
1559
1718
  this.#onReady = () => {
1560
1719
  };
@@ -1734,6 +1893,9 @@ var Capability = class {
1734
1893
  });
1735
1894
  }
1736
1895
  };
1896
+ getScheduleStore() {
1897
+ return this.#scheduleStore;
1898
+ }
1737
1899
  /**
1738
1900
  * Store is a key-value data store that can be used to persist data that should be shared
1739
1901
  * between requests. Each capability has its own store, and the data is persisted in Kubernetes
@@ -1828,7 +1990,7 @@ var Capability = class {
1828
1990
  * @returns
1829
1991
  */
1830
1992
  When = (model, kind4) => {
1831
- const matchedKind = (0, import_kubernetes_fluent_client6.modelToGroupVersionKind)(model.name);
1993
+ const matchedKind = (0, import_kubernetes_fluent_client7.modelToGroupVersionKind)(model.name);
1832
1994
  if (!matchedKind && !kind4) {
1833
1995
  throw new Error(`Kind not specified for ${model.name}`);
1834
1996
  }
@@ -1840,16 +2002,19 @@ var Capability = class {
1840
2002
  filters: {
1841
2003
  name: "",
1842
2004
  namespaces: [],
2005
+ regexNamespaces: [],
2006
+ regexName: "",
1843
2007
  labels: {},
1844
- annotations: {}
2008
+ annotations: {},
2009
+ deletionTimestamp: false
1845
2010
  }
1846
2011
  };
1847
2012
  const bindings = this.#bindings;
1848
2013
  const prefix = `${this.#name}: ${model.name}`;
1849
- const commonChain = { WithLabel, WithAnnotation, Mutate, Validate, Watch, Reconcile };
2014
+ const commonChain = { WithLabel, WithAnnotation, WithDeletionTimestamp, Mutate, Validate, Watch, Reconcile, Alias };
1850
2015
  const isNotEmpty = (value) => Object.keys(value).length > 0;
1851
2016
  const log = (message, cbString) => {
1852
- const filteredObj = (0, import_ramda6.pickBy)(isNotEmpty, binding.filters);
2017
+ const filteredObj = (0, import_ramda7.pickBy)(isNotEmpty, binding.filters);
1853
2018
  logger_default.info(`${message} configured for ${binding.event}`, prefix);
1854
2019
  logger_default.info(filteredObj, prefix);
1855
2020
  logger_default.debug(cbString, prefix);
@@ -1857,10 +2022,14 @@ var Capability = class {
1857
2022
  function Validate(validateCallback) {
1858
2023
  if (registerAdmission) {
1859
2024
  log("Validate Action", validateCallback.toString());
2025
+ const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
1860
2026
  bindings.push({
1861
2027
  ...binding,
1862
2028
  isValidate: true,
1863
- validateCallback
2029
+ validateCallback: async (req, logger = aliasLogger) => {
2030
+ logger_default.info(`Executing validate action with alias: ${binding.alias || "no alias provided"}`);
2031
+ return await validateCallback(req, logger);
2032
+ }
1864
2033
  });
1865
2034
  }
1866
2035
  return { Watch, Reconcile };
@@ -1868,10 +2037,14 @@ var Capability = class {
1868
2037
  function Mutate(mutateCallback) {
1869
2038
  if (registerAdmission) {
1870
2039
  log("Mutate Action", mutateCallback.toString());
2040
+ const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
1871
2041
  bindings.push({
1872
2042
  ...binding,
1873
2043
  isMutate: true,
1874
- mutateCallback
2044
+ mutateCallback: async (req, logger = aliasLogger) => {
2045
+ logger_default.info(`Executing mutation action with alias: ${binding.alias || "no alias provided"}`);
2046
+ await mutateCallback(req, logger);
2047
+ }
1875
2048
  });
1876
2049
  }
1877
2050
  return { Watch, Validate, Reconcile };
@@ -1879,28 +2052,80 @@ var Capability = class {
1879
2052
  function Watch(watchCallback) {
1880
2053
  if (registerWatch) {
1881
2054
  log("Watch Action", watchCallback.toString());
2055
+ const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
1882
2056
  bindings.push({
1883
2057
  ...binding,
1884
2058
  isWatch: true,
1885
- watchCallback
2059
+ watchCallback: async (update, phase, logger = aliasLogger) => {
2060
+ logger_default.info(`Executing watch action with alias: ${binding.alias || "no alias provided"}`);
2061
+ await watchCallback(update, phase, logger);
2062
+ }
1886
2063
  });
1887
2064
  }
2065
+ return { Finalize };
1888
2066
  }
1889
- function Reconcile(watchCallback) {
2067
+ function Reconcile(reconcileCallback) {
1890
2068
  if (registerWatch) {
1891
- log("Reconcile Action", watchCallback.toString());
2069
+ log("Reconcile Action", reconcileCallback.toString());
2070
+ const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
1892
2071
  bindings.push({
1893
2072
  ...binding,
1894
2073
  isWatch: true,
1895
2074
  isQueue: true,
1896
- watchCallback
2075
+ watchCallback: async (update, phase, logger = aliasLogger) => {
2076
+ logger_default.info(`Executing reconcile action with alias: ${binding.alias || "no alias provided"}`);
2077
+ await reconcileCallback(update, phase, logger);
2078
+ }
1897
2079
  });
1898
2080
  }
2081
+ return { Finalize };
2082
+ }
2083
+ function Finalize(finalizeCallback) {
2084
+ log("Finalize Action", finalizeCallback.toString());
2085
+ const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
2086
+ if (registerAdmission) {
2087
+ const mutateBinding = {
2088
+ ...binding,
2089
+ isMutate: true,
2090
+ isFinalize: true,
2091
+ event: "*" /* Any */,
2092
+ mutateCallback: addFinalizer
2093
+ };
2094
+ bindings.push(mutateBinding);
2095
+ }
2096
+ if (registerWatch) {
2097
+ const watchBinding = {
2098
+ ...binding,
2099
+ isWatch: true,
2100
+ isFinalize: true,
2101
+ event: "UPDATE" /* Update */,
2102
+ finalizeCallback: async (update, logger = aliasLogger) => {
2103
+ logger_default.info(`Executing finalize action with alias: ${binding.alias || "no alias provided"}`);
2104
+ await finalizeCallback(update, logger);
2105
+ }
2106
+ };
2107
+ bindings.push(watchBinding);
2108
+ }
1899
2109
  }
1900
2110
  function InNamespace(...namespaces) {
1901
2111
  logger_default.debug(`Add namespaces filter ${namespaces}`, prefix);
1902
2112
  binding.filters.namespaces.push(...namespaces);
1903
- return { ...commonChain, WithName };
2113
+ return { ...commonChain, WithName, WithNameRegex };
2114
+ }
2115
+ function InNamespaceRegex(...namespaces) {
2116
+ logger_default.debug(`Add regex namespaces filter ${namespaces}`, prefix);
2117
+ binding.filters.regexNamespaces.push(...namespaces.map((regex) => regex.source));
2118
+ return { ...commonChain, WithName, WithNameRegex };
2119
+ }
2120
+ function WithDeletionTimestamp() {
2121
+ logger_default.debug("Add deletionTimestamp filter");
2122
+ binding.filters.deletionTimestamp = true;
2123
+ return commonChain;
2124
+ }
2125
+ function WithNameRegex(regexName) {
2126
+ logger_default.debug(`Add regex name filter ${regexName}`, prefix);
2127
+ binding.filters.regexName = regexName.source;
2128
+ return commonChain;
1904
2129
  }
1905
2130
  function WithName(name) {
1906
2131
  logger_default.debug(`Add name filter ${name}`, prefix);
@@ -1917,12 +2142,21 @@ var Capability = class {
1917
2142
  binding.filters.annotations[key] = value;
1918
2143
  return commonChain;
1919
2144
  }
2145
+ function Alias(alias) {
2146
+ logger_default.debug(`Adding prefix alias ${alias}`, prefix);
2147
+ binding.alias = alias;
2148
+ return commonChain;
2149
+ }
1920
2150
  function bindEvent(event) {
1921
2151
  binding.event = event;
1922
2152
  return {
1923
2153
  ...commonChain,
1924
2154
  InNamespace,
1925
- WithName
2155
+ InNamespaceRegex,
2156
+ WithName,
2157
+ WithNameRegex,
2158
+ WithDeletionTimestamp,
2159
+ Alias
1926
2160
  };
1927
2161
  }
1928
2162
  return {