kubernetes-fluent-client 1.4.2 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fetch.d.ts CHANGED
@@ -17,7 +17,7 @@ export type FetchResponse<T> = {
17
17
  *
18
18
  * @param url The URL or Request object to fetch
19
19
  * @param init Additional options for the request
20
- * @returns
20
+ * @returns The parsed JSON response
21
21
  */
22
22
  export declare function fetch<T>(url: URL | RequestInfo, init?: RequestInit): Promise<FetchResponse<T>>;
23
23
  //# sourceMappingURL=fetch.d.ts.map
package/dist/fetch.js CHANGED
@@ -39,7 +39,7 @@ const node_fetch_1 = __importStar(require("node-fetch"));
39
39
  *
40
40
  * @param url The URL or Request object to fetch
41
41
  * @param init Additional options for the request
42
- * @returns
42
+ * @returns The parsed JSON response
43
43
  */
44
44
  async function fetch(url, init) {
45
45
  let data = undefined;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Configuration for the apply function.
3
+ */
4
+ export type ApplyCfg = {
5
+ /**
6
+ * Force the apply to be a create.
7
+ */
8
+ force?: boolean;
9
+ };
10
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/fluent/apply.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
4
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -6,6 +6,7 @@ import { Filters, K8sInit } from "./types";
6
6
  *
7
7
  * @param model - the model to use for the API
8
8
  * @param filters - (optional) filter overrides, can also be chained
9
+ * @returns a fluent API for the model
9
10
  */
10
11
  export declare function K8s<T extends GenericClass, K extends KubernetesObject = InstanceType<T>>(model: T, filters?: Filters): K8sInit<K>;
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fluent/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAMjF,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAsB,MAAM,SAAS,CAAC;AAI/D;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAC,EACtF,KAAK,EAAE,CAAC,EACR,OAAO,GAAE,OAAY,GACpB,OAAO,CAAC,CAAC,CAAC,CAuGZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fluent/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAMjF,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAsB,MAAM,SAAS,CAAC;AAI/D;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAC,EACtF,KAAK,EAAE,CAAC,EACR,OAAO,GAAE,OAAY,GACpB,OAAO,CAAC,CAAC,CAAC,CAmJZ"}
@@ -12,27 +12,45 @@ const watch_1 = require("./watch");
12
12
  *
13
13
  * @param model - the model to use for the API
14
14
  * @param filters - (optional) filter overrides, can also be chained
15
+ * @returns a fluent API for the model
15
16
  */
16
17
  function K8s(model, filters = {}) {
17
18
  const withFilters = { WithField, WithLabel, Get, Delete, Watch };
18
19
  const matchedKind = filters.kindOverride || (0, kinds_1.modelToGroupVersionKind)(model.name);
19
- function InNamespace(namespaces) {
20
+ /**
21
+ * @inheritdoc
22
+ * @see {@link K8sInit.InNamespace}
23
+ */
24
+ function InNamespace(namespace) {
20
25
  if (filters.namespace) {
21
26
  throw new Error(`Namespace already specified: ${filters.namespace}`);
22
27
  }
23
- filters.namespace = namespaces;
28
+ filters.namespace = namespace;
24
29
  return withFilters;
25
30
  }
31
+ /**
32
+ * @inheritdoc
33
+ * @see {@link K8sInit.WithField}
34
+ */
26
35
  function WithField(key, value) {
27
36
  filters.fields = filters.fields || {};
28
37
  filters.fields[key] = value;
29
38
  return withFilters;
30
39
  }
40
+ /**
41
+ * @inheritdoc
42
+ * @see {@link K8sInit.WithLabel}
43
+ */
31
44
  function WithLabel(key, value) {
32
45
  filters.labels = filters.labels || {};
33
46
  filters.labels[key] = value;
34
47
  return withFilters;
35
48
  }
49
+ /**
50
+ * Sync the filters with the provided payload.
51
+ *
52
+ * @param payload - the payload to sync with
53
+ */
36
54
  function syncFilters(payload) {
37
55
  // Ensure the payload has metadata
38
56
  payload.metadata = payload.metadata || {};
@@ -49,6 +67,10 @@ function K8s(model, filters = {}) {
49
67
  payload.kind = matchedKind.kind;
50
68
  }
51
69
  }
70
+ /**
71
+ * @inheritdoc
72
+ * @see {@link K8sInit.Get}
73
+ */
52
74
  async function Get(name) {
53
75
  if (name) {
54
76
  if (filters.name) {
@@ -58,6 +80,10 @@ function K8s(model, filters = {}) {
58
80
  }
59
81
  return (0, utils_1.k8sExec)(model, filters, "GET");
60
82
  }
83
+ /**
84
+ * @inheritdoc
85
+ * @see {@link K8sInit.Delete}
86
+ */
61
87
  async function Delete(filter) {
62
88
  if (typeof filter === "string") {
63
89
  filters.name = filter;
@@ -77,14 +103,26 @@ function K8s(model, filters = {}) {
77
103
  throw e;
78
104
  }
79
105
  }
80
- async function Apply(resource) {
106
+ /**
107
+ * @inheritdoc
108
+ * @see {@link K8sInit.Apply}
109
+ */
110
+ async function Apply(resource, applyCfg = { force: false }) {
81
111
  syncFilters(resource);
82
- return (0, utils_1.k8sExec)(model, filters, "APPLY", resource);
112
+ return (0, utils_1.k8sExec)(model, filters, "APPLY", resource, applyCfg);
83
113
  }
114
+ /**
115
+ * @inheritdoc
116
+ * @see {@link K8sInit.Create}
117
+ */
84
118
  async function Create(resource) {
85
119
  syncFilters(resource);
86
120
  return (0, utils_1.k8sExec)(model, filters, "POST", resource);
87
121
  }
122
+ /**
123
+ * @inheritdoc
124
+ * @see {@link K8sInit.Patch}
125
+ */
88
126
  async function Patch(payload) {
89
127
  // If there are no operations, throw an error
90
128
  if (payload.length < 1) {
@@ -92,6 +130,10 @@ function K8s(model, filters = {}) {
92
130
  }
93
131
  return (0, utils_1.k8sExec)(model, filters, "PATCH", payload);
94
132
  }
133
+ /**
134
+ * @inheritdoc
135
+ * @see {@link K8sInit.Watch}
136
+ */
95
137
  async function Watch(callback, watchCfg) {
96
138
  return (0, watch_1.ExecWatch)(model, filters, callback, watchCfg);
97
139
  }
@@ -6,8 +6,49 @@ const _1 = require(".");
6
6
  const utils_1 = require("./utils");
7
7
  // Setup mocks
8
8
  globals_1.jest.mock("./utils");
9
+ const generateFakePodManagedFields = (manager) => {
10
+ return [
11
+ {
12
+ apiVersion: "v1",
13
+ fieldsType: "FieldsV1",
14
+ fieldsV1: {
15
+ "f:metadata": {
16
+ "f:labels": {
17
+ "f:fake": {},
18
+ },
19
+ "f:spec": {
20
+ "f:containers": {
21
+ 'k:{"name":"fake"}': {
22
+ "f:image": {},
23
+ "f:name": {},
24
+ "f:resources": {
25
+ "f:limits": {
26
+ "f:cpu": {},
27
+ "f:memory": {},
28
+ },
29
+ "f:requests": {
30
+ "f:cpu": {},
31
+ "f:memory": {},
32
+ },
33
+ },
34
+ },
35
+ },
36
+ },
37
+ },
38
+ },
39
+ manager: manager,
40
+ operation: "Apply",
41
+ },
42
+ ];
43
+ };
9
44
  (0, globals_1.describe)("Kube", () => {
10
- const fakeResource = { metadata: { name: "fake", namespace: "default" } };
45
+ const fakeResource = {
46
+ metadata: {
47
+ name: "fake",
48
+ namespace: "default",
49
+ managedFields: generateFakePodManagedFields("pepr"),
50
+ },
51
+ };
11
52
  const mockedKubeExec = globals_1.jest.mocked(utils_1.k8sExec).mockResolvedValue(fakeResource);
12
53
  (0, globals_1.beforeEach)(() => {
13
54
  // Clear all instances and calls to constructor and all methods:
@@ -94,6 +135,14 @@ globals_1.jest.mock("./utils");
94
135
  const result = await kube.Apply({ metadata: { name: "fake" }, spec: { priority: 3 } });
95
136
  (0, globals_1.expect)(result).toEqual(fakeResource);
96
137
  });
138
+ (0, globals_1.it)("should allow force apply to resolve FieldManagerConflict", async () => {
139
+ const kube = (0, _1.K8s)(upstream_1.Pod);
140
+ const result = await kube.Apply({
141
+ metadata: { name: "fake", managedFields: generateFakePodManagedFields("kubectl") },
142
+ spec: { priority: 3 },
143
+ }, { force: true });
144
+ (0, globals_1.expect)(result).toEqual(fakeResource);
145
+ });
97
146
  (0, globals_1.it)("should throw an error if a Delete failed for a reason other than Not Found", async () => {
98
147
  mockedKubeExec.mockRejectedValueOnce({ status: 500 }); // Internal Server Error on first call
99
148
  const kube = (0, _1.K8s)(upstream_1.Pod);
@@ -3,6 +3,7 @@ import { Operation } from "fast-json-patch";
3
3
  import type { PartialDeep } from "type-fest";
4
4
  import { GenericClass, GroupVersionKind } from "../types";
5
5
  import { WatchCfg, WatchController } from "./watch";
6
+ import { ApplyCfg } from "./apply";
6
7
  /**
7
8
  * The Phase matched when using the K8s Watch API.
8
9
  */
@@ -19,6 +20,14 @@ export interface Filters {
19
20
  name?: string;
20
21
  namespace?: string;
21
22
  }
23
+ /**
24
+ * Get the resource or resources matching the filters.
25
+ * If no filters are specified, all resources will be returned.
26
+ * If a name is specified, only a single resource will be returned.
27
+ *
28
+ * @param name - (optional) the name of the resource to get
29
+ * @returns the resource or list of resources
30
+ */
22
31
  export type GetFunction<K extends KubernetesObject> = {
23
32
  (): Promise<KubernetesListObject<K>>;
24
33
  (name: string): Promise<K>;
@@ -31,15 +40,17 @@ export type K8sFilteredActions<K extends KubernetesObject> = {
31
40
  */
32
41
  Get: GetFunction<K>;
33
42
  /**
34
- * Delete the resource if it exists.
43
+ * Delete the resource matching the filters.
35
44
  *
36
45
  * @param filter - the resource or resource name to delete
37
46
  */
38
47
  Delete: (filter?: K | string) => Promise<void>;
39
48
  /**
49
+ * Watch the resource matching the filters.
40
50
  *
41
- * @param callback
42
- * @returns
51
+ * @param callback - the callback function to call when an event occurs
52
+ * @param watchCfg - (optional) watch configuration
53
+ * @returns a watch controller
43
54
  */
44
55
  Watch: (callback: (payload: K, phase: WatchPhase) => void, watchCfg?: WatchCfg) => Promise<WatchController>;
45
56
  };
@@ -47,15 +58,16 @@ export type K8sUnfilteredActions<K extends KubernetesObject> = {
47
58
  /**
48
59
  * Perform a server-side apply of the provided K8s resource.
49
60
  *
50
- * @param resource
51
- * @returns
61
+ * @param resource - the resource to apply
62
+ * @param applyCfg - (optional) apply configuration
63
+ * @returns the applied resource
52
64
  */
53
- Apply: (resource: PartialDeep<K>) => Promise<K>;
65
+ Apply: (resource: PartialDeep<K>, applyCfg?: ApplyCfg) => Promise<K>;
54
66
  /**
55
67
  * Create the provided K8s resource or throw an error if it already exists.
56
68
  *
57
- * @param resource
58
- * @returns
69
+ * @param resource - the resource to create
70
+ * @returns the created resource
59
71
  */
60
72
  Create: (resource: K) => Promise<K>;
61
73
  /**
@@ -75,18 +87,18 @@ export type K8sWithFilters<K extends KubernetesObject> = K8sFilteredActions<K> &
75
87
  *
76
88
  * ```ts
77
89
  * K8s(kind.Deployment)
78
- * .WithField("metadata.name", "bar")
79
- * .WithField("metadata.namespace", "qux")
80
- * .Delete(...)
90
+ * .WithField("metadata.name", "bar")
91
+ * .WithField("metadata.namespace", "qux")
92
+ * .Delete(...)
81
93
  * ```
82
94
  *
83
95
  * Will only delete the Deployment if it has the `metadata.name=bar` and `metadata.namespace=qux` fields.
84
96
  * Not all fields are supported, see https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/#supported-fields,
85
97
  * but Typescript will limit to only fields that exist on the resource.
86
98
  *
87
- * @param key The field key
88
- * @param value The field value
89
- * @returns
99
+ * @param key - the field key
100
+ * @param value - the field value
101
+ * @returns the fluent API
90
102
  */
91
103
  WithField: <P extends Paths<K>>(key: P, value: string) => K8sWithFilters<K>;
92
104
  /**
@@ -95,24 +107,25 @@ export type K8sWithFilters<K extends KubernetesObject> = K8sFilteredActions<K> &
95
107
  *
96
108
  * ```ts
97
109
  * K8s(kind.Deployment)
98
- * .WithLabel("foo", "bar")
99
- * .WithLabel("baz", "qux")
100
- * .Delete(...)
110
+ * .WithLabel("foo", "bar")
111
+ * .WithLabel("baz", "qux")
112
+ * .Delete(...)
101
113
  * ```
102
114
  *
103
115
  * Will only delete the Deployment if it has the`foo=bar` and `baz=qux` labels.
104
116
  *
105
- * @param key The label key
106
- * @param value (optional) The label value
117
+ * @param key - the label key
118
+ * @param value - the label value
119
+ * @returns the fluent API
107
120
  */
108
121
  WithLabel: (key: string, value: string) => K8sWithFilters<K>;
109
122
  };
110
123
  export type K8sInit<K extends KubernetesObject> = K8sWithFilters<K> & K8sUnfilteredActions<K> & {
111
124
  /**
112
- * Filter the query by the given namespace.
125
+ * Set the namespace filter.
113
126
  *
114
- * @param namespace
115
- * @returns
127
+ * @param namespace - the namespace to filter on
128
+ * @returns the fluent API
116
129
  */
117
130
  InNamespace: (namespace: string) => K8sWithFilters<K>;
118
131
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/fluent/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/fluent/types.ts"],"names":[],"mappings":"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"}
@@ -2,14 +2,15 @@
2
2
  import { URL } from "url";
3
3
  import { GenericClass } from "../types";
4
4
  import { FetchMethods, Filters } from "./types";
5
+ import { ApplyCfg } from "./apply";
5
6
  /**
6
7
  * Generate a path to a Kubernetes resource
7
8
  *
8
- * @param serverUrl
9
- * @param model
10
- * @param filters
11
- * @param excludeName
12
- * @returns
9
+ * @param serverUrl - the URL of the Kubernetes API server
10
+ * @param model - the model to use for the API
11
+ * @param filters - (optional) filter overrides, can also be chained
12
+ * @param excludeName - (optional) exclude the name from the path
13
+ * @returns the path to the resource
13
14
  */
14
15
  export declare function pathBuilder<T extends GenericClass>(serverUrl: string, model: T, filters: Filters, excludeName?: boolean): URL;
15
16
  /**
@@ -20,12 +21,23 @@ export declare function pathBuilder<T extends GenericClass>(serverUrl: string, m
20
21
  * - We have to create an agent to handle the TLS connection (for the custom CA + mTLS in some cases)
21
22
  * - The K8s lib uses request instead of node-fetch today so the object is slightly different
22
23
  *
23
- * @param method
24
- * @returns
24
+ * @param method - the HTTP method to use
25
+ * @returns the fetch options and server URL
25
26
  */
26
27
  export declare function k8sCfg(method: FetchMethods): Promise<{
27
28
  opts: import("node-fetch").RequestInit;
28
29
  serverUrl: string;
29
30
  }>;
30
- export declare function k8sExec<T extends GenericClass, K>(model: T, filters: Filters, method: FetchMethods, payload?: K | unknown): Promise<K>;
31
+ /**
32
+ * Execute a request against the Kubernetes API server.
33
+ *
34
+ * @param model - the model to use for the API
35
+ * @param filters - (optional) filter overrides, can also be chained
36
+ * @param method - the HTTP method to use
37
+ * @param payload - (optional) the payload to send
38
+ * @param applyCfg - (optional) configuration for the apply method
39
+ *
40
+ * @returns the parsed JSON response
41
+ */
42
+ export declare function k8sExec<T extends GenericClass, K>(model: T, filters: Filters, method: FetchMethods, payload?: K | unknown, applyCfg?: ApplyCfg): Promise<K>;
31
43
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/fluent/utils.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIhD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,WAAW,UAAQ,OAsDpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY;;;GAwBhD;AAED,wBAAsB,OAAO,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,EACrD,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,cA8BtB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/fluent/utils.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInC;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,WAAW,UAAQ,OAsDpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY;;;GAwBhD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,EACrD,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,EACrB,QAAQ,GAAE,QAA2B,cA8BtC"}
@@ -11,11 +11,11 @@ const SSA_CONTENT_TYPE = "application/apply-patch+yaml";
11
11
  /**
12
12
  * Generate a path to a Kubernetes resource
13
13
  *
14
- * @param serverUrl
15
- * @param model
16
- * @param filters
17
- * @param excludeName
18
- * @returns
14
+ * @param serverUrl - the URL of the Kubernetes API server
15
+ * @param model - the model to use for the API
16
+ * @param filters - (optional) filter overrides, can also be chained
17
+ * @param excludeName - (optional) exclude the name from the path
18
+ * @returns the path to the resource
19
19
  */
20
20
  function pathBuilder(serverUrl, model, filters, excludeName = false) {
21
21
  const matchedKind = filters.kindOverride || (0, kinds_1.modelToGroupVersionKind)(model.name);
@@ -66,8 +66,8 @@ exports.pathBuilder = pathBuilder;
66
66
  * - We have to create an agent to handle the TLS connection (for the custom CA + mTLS in some cases)
67
67
  * - The K8s lib uses request instead of node-fetch today so the object is slightly different
68
68
  *
69
- * @param method
70
- * @returns
69
+ * @param method - the HTTP method to use
70
+ * @returns the fetch options and server URL
71
71
  */
72
72
  async function k8sCfg(method) {
73
73
  const kubeConfig = new client_node_1.KubeConfig();
@@ -91,7 +91,18 @@ async function k8sCfg(method) {
91
91
  return { opts, serverUrl: cluster.server };
92
92
  }
93
93
  exports.k8sCfg = k8sCfg;
94
- async function k8sExec(model, filters, method, payload) {
94
+ /**
95
+ * Execute a request against the Kubernetes API server.
96
+ *
97
+ * @param model - the model to use for the API
98
+ * @param filters - (optional) filter overrides, can also be chained
99
+ * @param method - the HTTP method to use
100
+ * @param payload - (optional) the payload to send
101
+ * @param applyCfg - (optional) configuration for the apply method
102
+ *
103
+ * @returns the parsed JSON response
104
+ */
105
+ async function k8sExec(model, filters, method, payload, applyCfg = { force: false }) {
95
106
  const { opts, serverUrl } = await k8sCfg(method);
96
107
  const url = pathBuilder(serverUrl, model, filters, method === "POST");
97
108
  switch (opts.method) {
@@ -103,7 +114,7 @@ async function k8sExec(model, filters, method, payload) {
103
114
  opts.method = "PATCH";
104
115
  url.searchParams.set("fieldManager", "pepr");
105
116
  url.searchParams.set("fieldValidation", "Strict");
106
- url.searchParams.set("force", "false");
117
+ url.searchParams.set("force", applyCfg.force ? "true" : "false");
107
118
  break;
108
119
  }
109
120
  if (payload) {
@@ -25,7 +25,7 @@ globals_1.jest.mock("../fetch");
25
25
  };
26
26
  const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.Pod, filters);
27
27
  const expected = new URL("/api/v1/namespaces/default/pods/mypod?fieldSelector=iamafield%3Diamavalue&labelSelector=iamalabel%3Diamalabelvalue", serverUrl);
28
- (0, globals_1.expect)(result).toEqual(expected);
28
+ (0, globals_1.expect)(result.toString()).toEqual(expected.toString());
29
29
  });
30
30
  (0, globals_1.it)("Version not specified in a Kind", () => {
31
31
  const filters = {
@@ -7,13 +7,14 @@ import { Filters, WatchAction } from "./types";
7
7
  export type WatchController = {
8
8
  /**
9
9
  * Abort the watch.
10
+ *
10
11
  * @param reason optional reason for aborting the watch
11
- * @returns
12
12
  */
13
13
  abort: (reason?: string) => void;
14
14
  /**
15
15
  * Get the AbortSignal for the watch.
16
- * @returns
16
+ *
17
+ * @returns the AbortSignal
17
18
  */
18
19
  signal: () => AbortSignal;
19
20
  };
@@ -40,6 +41,12 @@ export type WatchCfg = {
40
41
  };
41
42
  /**
42
43
  * Execute a watch on the specified resource.
44
+ *
45
+ * @param model - the model to use for the API
46
+ * @param filters - (optional) filter overrides, can also be chained
47
+ * @param callback - the callback function to call when an event is received
48
+ * @param watchCfg - (optional) watch configuration
49
+ * @returns a WatchController to allow the watch to be aborted externally
43
50
  */
44
51
  export declare function ExecWatch<T extends GenericClass>(model: T, filters: Filters, callback: WatchAction<T>, watchCfg?: WatchCfg): Promise<WatchController>;
45
52
  //# sourceMappingURL=watch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/fluent/watch.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,SAAS,CAAC;AAG3D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;OAIG;IACH,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;OAGG;IACH,MAAM,EAAE,MAAM,WAAW,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC,CAAC;AAEF;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,YAAY,EACpD,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EACxB,QAAQ,GAAE,QAAa,4BAwJxB"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/fluent/watch.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,SAAS,CAAC;AAG3D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;OAIG;IACH,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,MAAM,EAAE,MAAM,WAAW,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,YAAY,EACpD,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EACxB,QAAQ,GAAE,QAAa,4BAmKxB"}
@@ -11,6 +11,12 @@ const node_fetch_1 = __importDefault(require("node-fetch"));
11
11
  const utils_1 = require("./utils");
12
12
  /**
13
13
  * Execute a watch on the specified resource.
14
+ *
15
+ * @param model - the model to use for the API
16
+ * @param filters - (optional) filter overrides, can also be chained
17
+ * @param callback - the callback function to call when an event is received
18
+ * @param watchCfg - (optional) watch configuration
19
+ * @returns a WatchController to allow the watch to be aborted externally
14
20
  */
15
21
  async function ExecWatch(model, filters, callback, watchCfg = {}) {
16
22
  watchCfg.logFn?.({ model, filters, watchCfg }, "ExecWatch");
@@ -39,6 +45,9 @@ async function ExecWatch(model, filters, callback, watchCfg = {}) {
39
45
  let abortController;
40
46
  // Create a wrapped AbortController to allow the watch to be aborted externally
41
47
  const abortWrapper = {};
48
+ /**
49
+ * Bind the abort controller to the wrapper.
50
+ */
42
51
  function bindAbortController() {
43
52
  // Create a new AbortController
44
53
  abortController = new AbortController();
@@ -48,6 +57,9 @@ async function ExecWatch(model, filters, callback, watchCfg = {}) {
48
57
  // Add the abort signal to the request options
49
58
  opts.signal = abortController.signal;
50
59
  }
60
+ /**
61
+ * The main watch runner. This will run until the process is terminated or the watch is aborted.
62
+ */
51
63
  async function runner() {
52
64
  let doneCalled = false;
53
65
  bindAbortController();
@@ -67,6 +79,7 @@ async function ExecWatch(model, filters, callback, watchCfg = {}) {
67
79
  }
68
80
  }
69
81
  };
82
+ // Cleanup the stream listeners
70
83
  const cleanup = () => {
71
84
  if (!doneCalled) {
72
85
  doneCalled = true;
@@ -109,7 +122,11 @@ async function ExecWatch(model, filters, callback, watchCfg = {}) {
109
122
  catch (e) {
110
123
  onError(e);
111
124
  }
112
- // On unhandled errors, retry the watch
125
+ /**
126
+ * Reload the watch.
127
+ *
128
+ * @param e - the error that caused the reload
129
+ */
113
130
  async function reload(e) {
114
131
  // If there are more attempts, retry the watch
115
132
  if (watchCfg.retryMax > retryCount) {
package/dist/kinds.d.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  import { GenericClass, GroupVersionKind } from "./types";
2
+ /**
3
+ * Converts a model name to a GroupVersionKind
4
+ *
5
+ * @param key The name of the model
6
+ * @returns The GroupVersionKind for the model
7
+ */
2
8
  export declare function modelToGroupVersionKind(key: string): GroupVersionKind;
3
9
  /**
4
10
  * Registers a new model and GroupVersionKind to be used within the fluent API.
@@ -1 +1 @@
1
- {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../src/kinds.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAwgBzD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAErE;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,UAAW,YAAY,oBAAoB,gBAAgB,SAUnF,CAAC"}
1
+ {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../src/kinds.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAujBzD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAErE;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,UAAW,YAAY,oBAAoB,gBAAgB,SAUnF,CAAC"}