kubernetes-fluent-client 3.6.2 → 3.6.3-nightly.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/fluent/index.d.ts.map +1 -1
- package/dist/fluent/index.js +12 -9
- package/dist/fluent/utils.d.ts +30 -3
- package/dist/fluent/utils.d.ts.map +1 -1
- package/dist/fluent/utils.js +52 -29
- package/dist/generate.d.ts +5 -3
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +4 -4
- package/package.json +7 -5
- package/src/fluent/index.ts +16 -9
- package/src/fluent/utils.ts +71 -32
- package/src/generate.ts +9 -7
|
@@ -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;AAOjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAS,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAuC,MAAM,mBAAmB,CAAC;AAKjF;;;;;;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,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fluent/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAOjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAS,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAuC,MAAM,mBAAmB,CAAC;AAKjF;;;;;;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,EAAE,CAAC,CAAC,CAgSf"}
|
package/dist/fluent/index.js
CHANGED
|
@@ -92,7 +92,7 @@ export function K8s(model, filters = {}) {
|
|
|
92
92
|
throw new Error("Kind must be Pod or have a selector");
|
|
93
93
|
}
|
|
94
94
|
try {
|
|
95
|
-
const object = await k8sExec(model, filters, FetchMethods.GET);
|
|
95
|
+
const object = await k8sExec(model, filters, { method: FetchMethods.GET });
|
|
96
96
|
if (kind !== "Pod") {
|
|
97
97
|
if (kind === "Service") {
|
|
98
98
|
const svc = object;
|
|
@@ -118,7 +118,7 @@ export function K8s(model, filters = {}) {
|
|
|
118
118
|
throw new Error(`Failed to get logs in KFC Logs function`);
|
|
119
119
|
}
|
|
120
120
|
const podModel = { ...model, name: "V1Pod" };
|
|
121
|
-
const logPromises = podList.map(po => k8sExec(podModel, { ...filters, name: po.metadata.name }, FetchMethods.LOG));
|
|
121
|
+
const logPromises = podList.map(po => k8sExec(podModel, { ...filters, name: po.metadata.name }, { method: FetchMethods.LOG }));
|
|
122
122
|
const responses = await Promise.all(logPromises);
|
|
123
123
|
const combinedString = responses.reduce((accumulator, currentString, i) => {
|
|
124
124
|
const prefixedLines = currentString
|
|
@@ -142,7 +142,7 @@ export function K8s(model, filters = {}) {
|
|
|
142
142
|
}
|
|
143
143
|
filters.name = name;
|
|
144
144
|
}
|
|
145
|
-
return k8sExec(model, filters, FetchMethods.GET);
|
|
145
|
+
return k8sExec(model, filters, { method: FetchMethods.GET });
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
148
148
|
* @inheritdoc
|
|
@@ -157,7 +157,7 @@ export function K8s(model, filters = {}) {
|
|
|
157
157
|
}
|
|
158
158
|
try {
|
|
159
159
|
// Try to delete the resource
|
|
160
|
-
await k8sExec(model, filters, FetchMethods.DELETE);
|
|
160
|
+
await k8sExec(model, filters, { method: FetchMethods.DELETE });
|
|
161
161
|
}
|
|
162
162
|
catch (e) {
|
|
163
163
|
// If the resource doesn't exist, ignore the error
|
|
@@ -173,7 +173,7 @@ export function K8s(model, filters = {}) {
|
|
|
173
173
|
*/
|
|
174
174
|
async function Apply(resource, applyCfg = { force: false }) {
|
|
175
175
|
syncFilters(resource);
|
|
176
|
-
return k8sExec(model, filters, FetchMethods.APPLY, resource, applyCfg);
|
|
176
|
+
return k8sExec(model, filters, { method: FetchMethods.APPLY, payload: resource }, applyCfg);
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
179
179
|
* @inheritdoc
|
|
@@ -181,7 +181,7 @@ export function K8s(model, filters = {}) {
|
|
|
181
181
|
*/
|
|
182
182
|
async function Create(resource) {
|
|
183
183
|
syncFilters(resource);
|
|
184
|
-
return k8sExec(model, filters, FetchMethods.POST, resource);
|
|
184
|
+
return k8sExec(model, filters, { method: FetchMethods.POST, payload: resource });
|
|
185
185
|
}
|
|
186
186
|
/**
|
|
187
187
|
* @inheritdoc
|
|
@@ -204,7 +204,10 @@ export function K8s(model, filters = {}) {
|
|
|
204
204
|
},
|
|
205
205
|
};
|
|
206
206
|
// Try to evict the resource
|
|
207
|
-
await k8sExec(model, filters,
|
|
207
|
+
await k8sExec(model, filters, {
|
|
208
|
+
method: FetchMethods.POST,
|
|
209
|
+
payload: evictionPayload,
|
|
210
|
+
});
|
|
208
211
|
}
|
|
209
212
|
catch (e) {
|
|
210
213
|
// If the resource doesn't exist, ignore the error
|
|
@@ -223,7 +226,7 @@ export function K8s(model, filters = {}) {
|
|
|
223
226
|
if (payload.length < 1) {
|
|
224
227
|
throw new Error("No operations specified");
|
|
225
228
|
}
|
|
226
|
-
return k8sExec(model, filters, FetchMethods.PATCH, payload);
|
|
229
|
+
return k8sExec(model, filters, { method: FetchMethods.PATCH, payload });
|
|
227
230
|
}
|
|
228
231
|
/**
|
|
229
232
|
* @inheritdoc
|
|
@@ -231,7 +234,7 @@ export function K8s(model, filters = {}) {
|
|
|
231
234
|
*/
|
|
232
235
|
async function PatchStatus(resource) {
|
|
233
236
|
syncFilters(resource);
|
|
234
|
-
return k8sExec(model, filters, FetchMethods.PATCH_STATUS, resource);
|
|
237
|
+
return k8sExec(model, filters, { method: FetchMethods.PATCH_STATUS, payload: resource });
|
|
235
238
|
}
|
|
236
239
|
/**
|
|
237
240
|
* @inheritdoc
|
package/dist/fluent/utils.d.ts
CHANGED
|
@@ -45,16 +45,43 @@ export declare function pathBuilder<T extends GenericClass>(serverUrl: string, m
|
|
|
45
45
|
* @returns the fetch options and server URL
|
|
46
46
|
*/
|
|
47
47
|
export declare function k8sCfg(method: FetchMethods): K8sConfigPromise;
|
|
48
|
+
/**
|
|
49
|
+
* Prepares and mutates the request options and URL for Kubernetes PATCH or APPLY operations.
|
|
50
|
+
*
|
|
51
|
+
* This function modifies the request's HTTP method, headers, and URL based on the operation type.
|
|
52
|
+
* It handles the following:
|
|
53
|
+
*
|
|
54
|
+
* - `PATCH_STATUS`: Converts the method to `PATCH`, appends `/status` to the path, sets merge patch headers,
|
|
55
|
+
* and rewrites the payload to contain only the `status` field.
|
|
56
|
+
* - `PATCH`: Sets the content type to `application/json-patch+json`.
|
|
57
|
+
* - `APPLY`: Converts the method to `PATCH`, sets server-side apply headers, and updates the query string
|
|
58
|
+
* with field manager and force options.
|
|
59
|
+
*
|
|
60
|
+
* @template K
|
|
61
|
+
* @param methodPayload - The original method and payload. May be mutated if `PATCH_STATUS` is used.
|
|
62
|
+
* @param opts - The request options.
|
|
63
|
+
* @param opts.method - The HTTP method (e.g. `PATCH`, `APPLY`, or `PATCH_STATUS`).
|
|
64
|
+
* @param opts.headers - The headers to be updated with the correct content type.
|
|
65
|
+
* @param url - The URL to mutate with subresource path or query parameters.
|
|
66
|
+
* @param applyCfg - Server-side apply options, such as `force`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function prepareRequestOptions<K>(methodPayload: MethodPayload<K>, opts: {
|
|
69
|
+
method?: string;
|
|
70
|
+
headers?: Record<string, string>;
|
|
71
|
+
}, url: URL, applyCfg: ApplyCfg): void;
|
|
72
|
+
export type MethodPayload<K> = {
|
|
73
|
+
method: FetchMethods;
|
|
74
|
+
payload?: K | unknown;
|
|
75
|
+
};
|
|
48
76
|
/**
|
|
49
77
|
* Execute a request against the Kubernetes API server.
|
|
50
78
|
*
|
|
51
79
|
* @param model - the model to use for the API
|
|
52
80
|
* @param filters - (optional) filter overrides, can also be chained
|
|
53
|
-
* @param
|
|
54
|
-
* @param payload - (optional) the payload to send
|
|
81
|
+
* @param methodPayload - method and payload for the request
|
|
55
82
|
* @param applyCfg - (optional) configuration for the apply method
|
|
56
83
|
*
|
|
57
84
|
* @returns the parsed JSON response
|
|
58
85
|
*/
|
|
59
|
-
export declare function k8sExec<T extends GenericClass, K>(model: T, filters: Filters,
|
|
86
|
+
export declare function k8sExec<T extends GenericClass, K>(model: T, filters: Filters, methodPayload: MethodPayload<K>, applyCfg?: ApplyCfg): Promise<K>;
|
|
60
87
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/fluent/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAS,UAAU,EAAE,MAAM,QAAQ,CAAC;AAI3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMtF;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBvF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAqBvE;AACD;;;;GAIG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMvD;AACD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,WAAW,UAAQ,OAwDpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CA+BnE;AASD
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/fluent/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAS,UAAU,EAAE,MAAM,QAAQ,CAAC;AAI3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMtF;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBvF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAqBvE;AACD;;;;GAIG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMvD;AACD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,WAAW,UAAQ,OAwDpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CA+BnE;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,EAC/B,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAC3D,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAsBN;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;CACvB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,EACrD,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,EAC/B,QAAQ,GAAE,QAA2B,cAkDtC"}
|
package/dist/fluent/utils.js
CHANGED
|
@@ -164,29 +164,70 @@ const isEvictionPayload = (payload) => payload !== null &&
|
|
|
164
164
|
typeof payload === "object" &&
|
|
165
165
|
"kind" in payload &&
|
|
166
166
|
payload.kind === "Eviction";
|
|
167
|
+
/**
|
|
168
|
+
* Prepares and mutates the request options and URL for Kubernetes PATCH or APPLY operations.
|
|
169
|
+
*
|
|
170
|
+
* This function modifies the request's HTTP method, headers, and URL based on the operation type.
|
|
171
|
+
* It handles the following:
|
|
172
|
+
*
|
|
173
|
+
* - `PATCH_STATUS`: Converts the method to `PATCH`, appends `/status` to the path, sets merge patch headers,
|
|
174
|
+
* and rewrites the payload to contain only the `status` field.
|
|
175
|
+
* - `PATCH`: Sets the content type to `application/json-patch+json`.
|
|
176
|
+
* - `APPLY`: Converts the method to `PATCH`, sets server-side apply headers, and updates the query string
|
|
177
|
+
* with field manager and force options.
|
|
178
|
+
*
|
|
179
|
+
* @template K
|
|
180
|
+
* @param methodPayload - The original method and payload. May be mutated if `PATCH_STATUS` is used.
|
|
181
|
+
* @param opts - The request options.
|
|
182
|
+
* @param opts.method - The HTTP method (e.g. `PATCH`, `APPLY`, or `PATCH_STATUS`).
|
|
183
|
+
* @param opts.headers - The headers to be updated with the correct content type.
|
|
184
|
+
* @param url - The URL to mutate with subresource path or query parameters.
|
|
185
|
+
* @param applyCfg - Server-side apply options, such as `force`.
|
|
186
|
+
*/
|
|
187
|
+
export function prepareRequestOptions(methodPayload, opts, url, applyCfg) {
|
|
188
|
+
switch (opts.method) {
|
|
189
|
+
// PATCH_STATUS is a special case that uses the PATCH method on status subresources
|
|
190
|
+
case "PATCH_STATUS":
|
|
191
|
+
opts.method = "PATCH";
|
|
192
|
+
url.pathname = `${url.pathname}/status`;
|
|
193
|
+
opts.headers["Content-Type"] = PatchStrategy.MergePatch;
|
|
194
|
+
methodPayload.payload = { status: methodPayload.payload.status };
|
|
195
|
+
break;
|
|
196
|
+
case "PATCH":
|
|
197
|
+
opts.headers["Content-Type"] = PatchStrategy.JsonPatch;
|
|
198
|
+
break;
|
|
199
|
+
case "APPLY":
|
|
200
|
+
opts.headers["Content-Type"] = SSA_CONTENT_TYPE;
|
|
201
|
+
opts.method = "PATCH";
|
|
202
|
+
url.searchParams.set("fieldManager", "pepr");
|
|
203
|
+
url.searchParams.set("fieldValidation", "Strict");
|
|
204
|
+
url.searchParams.set("force", applyCfg.force ? "true" : "false");
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
167
208
|
/**
|
|
168
209
|
* Execute a request against the Kubernetes API server.
|
|
169
210
|
*
|
|
170
211
|
* @param model - the model to use for the API
|
|
171
212
|
* @param filters - (optional) filter overrides, can also be chained
|
|
172
|
-
* @param
|
|
173
|
-
* @param payload - (optional) the payload to send
|
|
213
|
+
* @param methodPayload - method and payload for the request
|
|
174
214
|
* @param applyCfg - (optional) configuration for the apply method
|
|
175
215
|
*
|
|
176
216
|
* @returns the parsed JSON response
|
|
177
217
|
*/
|
|
178
|
-
export async function k8sExec(model, filters,
|
|
218
|
+
export async function k8sExec(model, filters, methodPayload, applyCfg = { force: false }) {
|
|
179
219
|
const reconstruct = async (method) => {
|
|
180
220
|
const configMethod = method === FetchMethods.LOG ? FetchMethods.GET : method;
|
|
181
221
|
const { opts, serverUrl } = await k8sCfg(configMethod);
|
|
182
222
|
// Build the base path once, using excludeName only for standard POST requests
|
|
183
|
-
const shouldExcludeName = method ===
|
|
223
|
+
const shouldExcludeName = method === FetchMethods.POST &&
|
|
224
|
+
!(methodPayload.payload && isEvictionPayload(methodPayload.payload));
|
|
184
225
|
const baseUrl = pathBuilder(serverUrl.toString(), model, filters, shouldExcludeName);
|
|
185
226
|
// Append appropriate subresource paths
|
|
186
|
-
if (payload && isEvictionPayload(payload)) {
|
|
227
|
+
if (methodPayload.payload && isEvictionPayload(methodPayload.payload)) {
|
|
187
228
|
baseUrl.pathname = `${baseUrl.pathname}/eviction`;
|
|
188
229
|
}
|
|
189
|
-
else if (method ===
|
|
230
|
+
else if (method === FetchMethods.LOG) {
|
|
190
231
|
baseUrl.pathname = `${baseUrl.pathname}/log`;
|
|
191
232
|
}
|
|
192
233
|
return {
|
|
@@ -194,35 +235,17 @@ export async function k8sExec(model, filters, method, payload, applyCfg = { forc
|
|
|
194
235
|
opts,
|
|
195
236
|
};
|
|
196
237
|
};
|
|
197
|
-
const { opts, serverUrl } = await reconstruct(method);
|
|
238
|
+
const { opts, serverUrl } = await reconstruct(methodPayload.method);
|
|
198
239
|
const url = serverUrl instanceof URL ? serverUrl : new URL(serverUrl);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
opts.method = "PATCH";
|
|
203
|
-
url.pathname = `${url.pathname}/status`;
|
|
204
|
-
opts.headers["Content-Type"] = PatchStrategy.MergePatch;
|
|
205
|
-
payload = { status: payload.status };
|
|
206
|
-
break;
|
|
207
|
-
case "PATCH":
|
|
208
|
-
opts.headers["Content-Type"] = PatchStrategy.JsonPatch;
|
|
209
|
-
break;
|
|
210
|
-
case "APPLY":
|
|
211
|
-
opts.headers["Content-Type"] = SSA_CONTENT_TYPE;
|
|
212
|
-
opts.method = "PATCH";
|
|
213
|
-
url.searchParams.set("fieldManager", "pepr");
|
|
214
|
-
url.searchParams.set("fieldValidation", "Strict");
|
|
215
|
-
url.searchParams.set("force", applyCfg.force ? "true" : "false");
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
if (payload) {
|
|
219
|
-
opts.body = JSON.stringify(payload);
|
|
240
|
+
prepareRequestOptions(methodPayload, opts, url, applyCfg);
|
|
241
|
+
if (methodPayload.payload) {
|
|
242
|
+
opts.body = JSON.stringify(methodPayload.payload);
|
|
220
243
|
}
|
|
221
244
|
const resp = await fetch(url, opts);
|
|
222
245
|
if (resp.ok) {
|
|
223
246
|
return resp.data;
|
|
224
247
|
}
|
|
225
|
-
if (resp.status === 404 && method ===
|
|
248
|
+
if (resp.status === 404 && methodPayload.method === FetchMethods.PATCH_STATUS) {
|
|
226
249
|
resp.statusText =
|
|
227
250
|
"Not Found" + " (NOTE: This error is expected if the resource has no status subresource)";
|
|
228
251
|
}
|
package/dist/generate.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { InputData, TargetLanguage } from "quicktype-core";
|
|
1
|
+
import { InputData, TargetLanguage, quicktype } from "quicktype-core";
|
|
2
2
|
import { CustomResourceDefinition } from "./upstream.js";
|
|
3
3
|
import { LogFn } from "./types.js";
|
|
4
|
+
export type QuicktypeLang = Parameters<typeof quicktype>[0]["lang"];
|
|
4
5
|
export interface GenerateOptions {
|
|
5
6
|
source: string;
|
|
6
7
|
directory?: string;
|
|
7
8
|
plain?: boolean;
|
|
8
|
-
language
|
|
9
|
+
language: QuicktypeLang;
|
|
9
10
|
npmPackage?: string;
|
|
10
11
|
logFn: LogFn;
|
|
11
12
|
noPost?: boolean;
|
|
@@ -35,9 +36,10 @@ export declare function prepareInputData(name: string, schema: string): Promise<
|
|
|
35
36
|
* Generates TypeScript types using quicktype.
|
|
36
37
|
*
|
|
37
38
|
* @param inputData - The input data for quicktype.
|
|
39
|
+
* @param opts - The options for generating the TypeScript types.
|
|
38
40
|
* @returns A promise that resolves to an array of generated TypeScript type lines.
|
|
39
41
|
*/
|
|
40
|
-
export declare function generateTypes(inputData: InputData): Promise<string[]>;
|
|
42
|
+
export declare function generateTypes(inputData: InputData, opts: GenerateOptions): Promise<string[]>;
|
|
41
43
|
/**
|
|
42
44
|
* Writes the processed lines to the output file.
|
|
43
45
|
*
|
package/dist/generate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,SAAS,EAET,cAAc,
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,SAAS,EAET,cAAc,EACd,SAAS,EACV,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,eAAe,GACpB,OAAO,CACR;IACE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,wBAAwB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB,EAAE,CACJ,CAuCA;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAYvF;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CASnB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,MAAM,GAAG,cAAc,GAChC,IAAI,CAON;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC,CA0B/F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAMtD;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAC5D;IACE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,wBAAwB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB,EAAE,CACJ,CA8BA"}
|
package/dist/generate.js
CHANGED
|
@@ -32,7 +32,7 @@ export async function convertCRDtoTS(crd, opts) {
|
|
|
32
32
|
const schema = JSON.stringify(match.schema.openAPIV3Schema);
|
|
33
33
|
opts.logFn(`- Generating ${crd.spec.group}/${match.name} types for ${name}`);
|
|
34
34
|
const inputData = await prepareInputData(name, schema);
|
|
35
|
-
const generatedTypes = await generateTypes(inputData);
|
|
35
|
+
const generatedTypes = await generateTypes(inputData, opts);
|
|
36
36
|
const fileName = `${name.toLowerCase()}-${match.name.toLowerCase()}`;
|
|
37
37
|
writeGeneratedFile(fileName, opts.directory || "", generatedTypes, opts.language || "ts");
|
|
38
38
|
results[fileName] = generatedTypes;
|
|
@@ -61,14 +61,14 @@ export async function prepareInputData(name, schema) {
|
|
|
61
61
|
* Generates TypeScript types using quicktype.
|
|
62
62
|
*
|
|
63
63
|
* @param inputData - The input data for quicktype.
|
|
64
|
+
* @param opts - The options for generating the TypeScript types.
|
|
64
65
|
* @returns A promise that resolves to an array of generated TypeScript type lines.
|
|
65
66
|
*/
|
|
66
|
-
export async function generateTypes(inputData) {
|
|
67
|
-
// If the language is not specified, default to TypeScript
|
|
67
|
+
export async function generateTypes(inputData, opts) {
|
|
68
68
|
// Generate the types
|
|
69
69
|
const out = await quicktype({
|
|
70
70
|
inputData,
|
|
71
|
-
lang:
|
|
71
|
+
lang: opts.language,
|
|
72
72
|
rendererOptions: { "just-types": "true" },
|
|
73
73
|
});
|
|
74
74
|
return out.lines;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kubernetes-fluent-client",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.3-nightly.1",
|
|
4
4
|
"description": "A @kubernetes/client-node fluent API wrapper that leverages K8s Server Side Apply.",
|
|
5
5
|
"bin": "./dist/cli.js",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"semantic-release": "semantic-release",
|
|
41
41
|
"test": "vitest src run --coverage",
|
|
42
42
|
"test:e2e": "vitest run e2e/",
|
|
43
|
-
"test:e2e:prep-crds": "kubectl apply -f test/ && npx tsx src/cli.ts crd ./test/datastore.crd.yaml e2e && npx tsx src/cli.ts crd https://raw.githubusercontent.com/defenseunicorns/kubernetes-fluent-client/refs/heads/main/test/webapp.crd.yaml e2e",
|
|
43
|
+
"test:e2e:prep-crds": "kubectl apply -f test/ && npx tsx src/cli.ts crd ./test/datastore.crd.yaml e2e && npx tsx src/cli.ts crd https://raw.githubusercontent.com/defenseunicorns/kubernetes-fluent-client/refs/heads/main/test/webapp.crd.yaml e2e && npx tsx src/cli.ts crd https://raw.githubusercontent.com/defenseunicorns/kubernetes-fluent-client/refs/heads/main/test/webapp.crd.yaml -l json-schema e2e/schemas/webapp",
|
|
44
44
|
"test:e2e:prep-cluster": "k3d cluster create kfc-dev --k3s-arg '--debug@server:0' --wait && kubectl rollout status deployment -n kube-system",
|
|
45
45
|
"test:e2e:prep-image": "npm run build && npm pack && npm i kubernetes-fluent-client-0.0.0-development.tgz --no-save",
|
|
46
46
|
"test:e2e:run": "npm run test:e2e:prep-cluster && npm run test:e2e:prep-crds && npm run test:e2e:prep-image && npm run test:e2e && npm run test:e2e:cleanup",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"fast-json-patch": "3.1.1",
|
|
55
55
|
"http-status-codes": "2.3.0",
|
|
56
56
|
"node-fetch": "2.7.0",
|
|
57
|
-
"quicktype-core": "23.2.
|
|
57
|
+
"quicktype-core": "23.2.6",
|
|
58
58
|
"type-fest": "^4.39.1",
|
|
59
59
|
"undici": "^7.7.0",
|
|
60
60
|
"yargs": "18.0.0"
|
|
@@ -65,13 +65,15 @@
|
|
|
65
65
|
"@eslint/eslintrc": "^3.1.0",
|
|
66
66
|
"@eslint/js": "^9.14.0",
|
|
67
67
|
"@types/byline": "4.2.36",
|
|
68
|
+
"@types/command-line-args": "^5.2.3",
|
|
68
69
|
"@types/readable-stream": "4.0.21",
|
|
69
70
|
"@types/urijs": "^1.19.25",
|
|
70
71
|
"@types/ws": "^8.18.1",
|
|
71
72
|
"@types/yargs": "17.0.33",
|
|
72
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
73
|
-
"@typescript-eslint/parser": "8.
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "8.34.0",
|
|
74
|
+
"@typescript-eslint/parser": "8.34.0",
|
|
74
75
|
"@vitest/coverage-v8": "^3.2.1",
|
|
76
|
+
"command-line-args": "^6.0.1",
|
|
75
77
|
"eslint-plugin-jsdoc": "50.7.1",
|
|
76
78
|
"globals": "^16.0.0",
|
|
77
79
|
"husky": "^9.1.6",
|
package/src/fluent/index.ts
CHANGED
|
@@ -115,7 +115,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
try {
|
|
118
|
-
const object = await k8sExec<T, K>(model, filters, FetchMethods.GET);
|
|
118
|
+
const object = await k8sExec<T, K>(model, filters, { method: FetchMethods.GET });
|
|
119
119
|
|
|
120
120
|
if (kind !== "Pod") {
|
|
121
121
|
if (kind === "Service") {
|
|
@@ -145,7 +145,11 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
145
145
|
|
|
146
146
|
const podModel = { ...model, name: "V1Pod" };
|
|
147
147
|
const logPromises = podList.map(po =>
|
|
148
|
-
k8sExec<T, string>(
|
|
148
|
+
k8sExec<T, string>(
|
|
149
|
+
podModel,
|
|
150
|
+
{ ...filters, name: po.metadata!.name! },
|
|
151
|
+
{ method: FetchMethods.LOG },
|
|
152
|
+
),
|
|
149
153
|
);
|
|
150
154
|
|
|
151
155
|
const responses = await Promise.all(logPromises);
|
|
@@ -180,7 +184,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
180
184
|
filters.name = name;
|
|
181
185
|
}
|
|
182
186
|
|
|
183
|
-
return k8sExec<T, K | KubernetesListObject<K>>(model, filters, FetchMethods.GET);
|
|
187
|
+
return k8sExec<T, K | KubernetesListObject<K>>(model, filters, { method: FetchMethods.GET });
|
|
184
188
|
}
|
|
185
189
|
|
|
186
190
|
/**
|
|
@@ -196,7 +200,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
196
200
|
|
|
197
201
|
try {
|
|
198
202
|
// Try to delete the resource
|
|
199
|
-
await k8sExec<T, void>(model, filters, FetchMethods.DELETE);
|
|
203
|
+
await k8sExec<T, void>(model, filters, { method: FetchMethods.DELETE });
|
|
200
204
|
} catch (e) {
|
|
201
205
|
// If the resource doesn't exist, ignore the error
|
|
202
206
|
if (e.status === StatusCodes.NOT_FOUND) {
|
|
@@ -216,7 +220,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
216
220
|
applyCfg: ApplyCfg = { force: false },
|
|
217
221
|
): Promise<K> {
|
|
218
222
|
syncFilters(resource as K);
|
|
219
|
-
return k8sExec(model, filters, FetchMethods.APPLY, resource, applyCfg);
|
|
223
|
+
return k8sExec(model, filters, { method: FetchMethods.APPLY, payload: resource }, applyCfg);
|
|
220
224
|
}
|
|
221
225
|
|
|
222
226
|
/**
|
|
@@ -225,7 +229,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
225
229
|
*/
|
|
226
230
|
async function Create(resource: K): Promise<K> {
|
|
227
231
|
syncFilters(resource);
|
|
228
|
-
return k8sExec(model, filters, FetchMethods.POST, resource);
|
|
232
|
+
return k8sExec(model, filters, { method: FetchMethods.POST, payload: resource });
|
|
229
233
|
}
|
|
230
234
|
|
|
231
235
|
/**
|
|
@@ -249,7 +253,10 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
249
253
|
},
|
|
250
254
|
};
|
|
251
255
|
// Try to evict the resource
|
|
252
|
-
await k8sExec<T, void>(model, filters,
|
|
256
|
+
await k8sExec<T, void>(model, filters, {
|
|
257
|
+
method: FetchMethods.POST,
|
|
258
|
+
payload: evictionPayload,
|
|
259
|
+
});
|
|
253
260
|
} catch (e) {
|
|
254
261
|
// If the resource doesn't exist, ignore the error
|
|
255
262
|
if (e.status === StatusCodes.NOT_FOUND) {
|
|
@@ -269,7 +276,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
269
276
|
throw new Error("No operations specified");
|
|
270
277
|
}
|
|
271
278
|
|
|
272
|
-
return k8sExec(model, filters, FetchMethods.PATCH, payload);
|
|
279
|
+
return k8sExec(model, filters, { method: FetchMethods.PATCH, payload });
|
|
273
280
|
}
|
|
274
281
|
|
|
275
282
|
/**
|
|
@@ -278,7 +285,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
278
285
|
*/
|
|
279
286
|
async function PatchStatus(resource: PartialDeep<K>): Promise<K> {
|
|
280
287
|
syncFilters(resource as K);
|
|
281
|
-
return k8sExec(model, filters, FetchMethods.PATCH_STATUS, resource);
|
|
288
|
+
return k8sExec(model, filters, { method: FetchMethods.PATCH_STATUS, payload: resource });
|
|
282
289
|
}
|
|
283
290
|
|
|
284
291
|
/**
|
package/src/fluent/utils.ts
CHANGED
|
@@ -203,13 +203,66 @@ const isEvictionPayload = (payload: unknown): payload is Eviction =>
|
|
|
203
203
|
"kind" in payload &&
|
|
204
204
|
(payload as { kind: string }).kind === "Eviction";
|
|
205
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Prepares and mutates the request options and URL for Kubernetes PATCH or APPLY operations.
|
|
208
|
+
*
|
|
209
|
+
* This function modifies the request's HTTP method, headers, and URL based on the operation type.
|
|
210
|
+
* It handles the following:
|
|
211
|
+
*
|
|
212
|
+
* - `PATCH_STATUS`: Converts the method to `PATCH`, appends `/status` to the path, sets merge patch headers,
|
|
213
|
+
* and rewrites the payload to contain only the `status` field.
|
|
214
|
+
* - `PATCH`: Sets the content type to `application/json-patch+json`.
|
|
215
|
+
* - `APPLY`: Converts the method to `PATCH`, sets server-side apply headers, and updates the query string
|
|
216
|
+
* with field manager and force options.
|
|
217
|
+
*
|
|
218
|
+
* @template K
|
|
219
|
+
* @param methodPayload - The original method and payload. May be mutated if `PATCH_STATUS` is used.
|
|
220
|
+
* @param opts - The request options.
|
|
221
|
+
* @param opts.method - The HTTP method (e.g. `PATCH`, `APPLY`, or `PATCH_STATUS`).
|
|
222
|
+
* @param opts.headers - The headers to be updated with the correct content type.
|
|
223
|
+
* @param url - The URL to mutate with subresource path or query parameters.
|
|
224
|
+
* @param applyCfg - Server-side apply options, such as `force`.
|
|
225
|
+
*/
|
|
226
|
+
export function prepareRequestOptions<K>(
|
|
227
|
+
methodPayload: MethodPayload<K>,
|
|
228
|
+
opts: { method?: string; headers?: Record<string, string> },
|
|
229
|
+
url: URL,
|
|
230
|
+
applyCfg: ApplyCfg,
|
|
231
|
+
): void {
|
|
232
|
+
switch (opts.method) {
|
|
233
|
+
// PATCH_STATUS is a special case that uses the PATCH method on status subresources
|
|
234
|
+
case "PATCH_STATUS":
|
|
235
|
+
opts.method = "PATCH";
|
|
236
|
+
url.pathname = `${url.pathname}/status`;
|
|
237
|
+
(opts.headers as Record<string, string>)["Content-Type"] = PatchStrategy.MergePatch;
|
|
238
|
+
methodPayload.payload = { status: (methodPayload.payload as { status: unknown }).status };
|
|
239
|
+
break;
|
|
240
|
+
|
|
241
|
+
case "PATCH":
|
|
242
|
+
(opts.headers as Record<string, string>)["Content-Type"] = PatchStrategy.JsonPatch;
|
|
243
|
+
break;
|
|
244
|
+
|
|
245
|
+
case "APPLY":
|
|
246
|
+
(opts.headers as Record<string, string>)["Content-Type"] = SSA_CONTENT_TYPE;
|
|
247
|
+
opts.method = "PATCH";
|
|
248
|
+
url.searchParams.set("fieldManager", "pepr");
|
|
249
|
+
url.searchParams.set("fieldValidation", "Strict");
|
|
250
|
+
url.searchParams.set("force", applyCfg.force ? "true" : "false");
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type MethodPayload<K> = {
|
|
256
|
+
method: FetchMethods;
|
|
257
|
+
payload?: K | unknown;
|
|
258
|
+
};
|
|
259
|
+
|
|
206
260
|
/**
|
|
207
261
|
* Execute a request against the Kubernetes API server.
|
|
208
262
|
*
|
|
209
263
|
* @param model - the model to use for the API
|
|
210
264
|
* @param filters - (optional) filter overrides, can also be chained
|
|
211
|
-
* @param
|
|
212
|
-
* @param payload - (optional) the payload to send
|
|
265
|
+
* @param methodPayload - method and payload for the request
|
|
213
266
|
* @param applyCfg - (optional) configuration for the apply method
|
|
214
267
|
*
|
|
215
268
|
* @returns the parsed JSON response
|
|
@@ -217,8 +270,7 @@ const isEvictionPayload = (payload: unknown): payload is Eviction =>
|
|
|
217
270
|
export async function k8sExec<T extends GenericClass, K>(
|
|
218
271
|
model: T,
|
|
219
272
|
filters: Filters,
|
|
220
|
-
|
|
221
|
-
payload?: K | unknown,
|
|
273
|
+
methodPayload: MethodPayload<K>,
|
|
222
274
|
applyCfg: ApplyCfg = { force: false },
|
|
223
275
|
) {
|
|
224
276
|
const reconstruct = async (method: FetchMethods): K8sConfigPromise => {
|
|
@@ -226,13 +278,15 @@ export async function k8sExec<T extends GenericClass, K>(
|
|
|
226
278
|
const { opts, serverUrl } = await k8sCfg(configMethod);
|
|
227
279
|
|
|
228
280
|
// Build the base path once, using excludeName only for standard POST requests
|
|
229
|
-
const shouldExcludeName =
|
|
281
|
+
const shouldExcludeName =
|
|
282
|
+
method === FetchMethods.POST &&
|
|
283
|
+
!(methodPayload.payload && isEvictionPayload(methodPayload.payload));
|
|
230
284
|
const baseUrl = pathBuilder(serverUrl.toString(), model, filters, shouldExcludeName);
|
|
231
285
|
|
|
232
286
|
// Append appropriate subresource paths
|
|
233
|
-
if (payload && isEvictionPayload(payload)) {
|
|
287
|
+
if (methodPayload.payload && isEvictionPayload(methodPayload.payload)) {
|
|
234
288
|
baseUrl.pathname = `${baseUrl.pathname}/eviction`;
|
|
235
|
-
} else if (method ===
|
|
289
|
+
} else if (method === FetchMethods.LOG) {
|
|
236
290
|
baseUrl.pathname = `${baseUrl.pathname}/log`;
|
|
237
291
|
}
|
|
238
292
|
|
|
@@ -242,33 +296,18 @@ export async function k8sExec<T extends GenericClass, K>(
|
|
|
242
296
|
};
|
|
243
297
|
};
|
|
244
298
|
|
|
245
|
-
const { opts, serverUrl } = await reconstruct(method);
|
|
299
|
+
const { opts, serverUrl } = await reconstruct(methodPayload.method);
|
|
246
300
|
const url: URL = serverUrl instanceof URL ? serverUrl : new URL(serverUrl);
|
|
247
301
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
payload = { status: (payload as { status: unknown }).status };
|
|
255
|
-
break;
|
|
256
|
-
|
|
257
|
-
case "PATCH":
|
|
258
|
-
(opts.headers as Record<string, string>)["Content-Type"] = PatchStrategy.JsonPatch;
|
|
259
|
-
break;
|
|
260
|
-
|
|
261
|
-
case "APPLY":
|
|
262
|
-
(opts.headers as Record<string, string>)["Content-Type"] = SSA_CONTENT_TYPE;
|
|
263
|
-
opts.method = "PATCH";
|
|
264
|
-
url.searchParams.set("fieldManager", "pepr");
|
|
265
|
-
url.searchParams.set("fieldValidation", "Strict");
|
|
266
|
-
url.searchParams.set("force", applyCfg.force ? "true" : "false");
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
302
|
+
prepareRequestOptions(
|
|
303
|
+
methodPayload,
|
|
304
|
+
opts as { method?: string; headers?: Record<string, string> },
|
|
305
|
+
url,
|
|
306
|
+
applyCfg,
|
|
307
|
+
);
|
|
269
308
|
|
|
270
|
-
if (payload) {
|
|
271
|
-
opts.body = JSON.stringify(payload);
|
|
309
|
+
if (methodPayload.payload) {
|
|
310
|
+
opts.body = JSON.stringify(methodPayload.payload);
|
|
272
311
|
}
|
|
273
312
|
const resp = await fetch<K>(url, opts);
|
|
274
313
|
|
|
@@ -276,7 +315,7 @@ export async function k8sExec<T extends GenericClass, K>(
|
|
|
276
315
|
return resp.data;
|
|
277
316
|
}
|
|
278
317
|
|
|
279
|
-
if (resp.status === 404 && method ===
|
|
318
|
+
if (resp.status === 404 && methodPayload.method === FetchMethods.PATCH_STATUS) {
|
|
280
319
|
resp.statusText =
|
|
281
320
|
"Not Found" + " (NOTE: This error is expected if the resource has no status subresource)";
|
|
282
321
|
}
|
package/src/generate.ts
CHANGED
|
@@ -16,12 +16,12 @@ import { fetch } from "./fetch.js";
|
|
|
16
16
|
import { K8s } from "./fluent/index.js";
|
|
17
17
|
import { CustomResourceDefinition } from "./upstream.js";
|
|
18
18
|
import { LogFn } from "./types.js";
|
|
19
|
-
|
|
19
|
+
export type QuicktypeLang = Parameters<typeof quicktype>[0]["lang"];
|
|
20
20
|
export interface GenerateOptions {
|
|
21
21
|
source: string; // URL, file path, or K8s CRD name
|
|
22
22
|
directory?: string; // Output directory path
|
|
23
23
|
plain?: boolean; // Disable fluent client wrapping
|
|
24
|
-
language
|
|
24
|
+
language: QuicktypeLang; // Language for type generation (default: "ts")
|
|
25
25
|
npmPackage?: string; // Override NPM package
|
|
26
26
|
logFn: LogFn; // Log function callback
|
|
27
27
|
noPost?: boolean; // Enable/disable post-processing
|
|
@@ -73,7 +73,7 @@ export async function convertCRDtoTS(
|
|
|
73
73
|
opts.logFn(`- Generating ${crd.spec.group}/${match.name} types for ${name}`);
|
|
74
74
|
|
|
75
75
|
const inputData = await prepareInputData(name, schema);
|
|
76
|
-
const generatedTypes = await generateTypes(inputData);
|
|
76
|
+
const generatedTypes = await generateTypes(inputData, opts);
|
|
77
77
|
|
|
78
78
|
const fileName = `${name.toLowerCase()}-${match.name.toLowerCase()}`;
|
|
79
79
|
writeGeneratedFile(fileName, opts.directory || "", generatedTypes, opts.language || "ts");
|
|
@@ -110,15 +110,17 @@ export async function prepareInputData(name: string, schema: string): Promise<In
|
|
|
110
110
|
* Generates TypeScript types using quicktype.
|
|
111
111
|
*
|
|
112
112
|
* @param inputData - The input data for quicktype.
|
|
113
|
+
* @param opts - The options for generating the TypeScript types.
|
|
113
114
|
* @returns A promise that resolves to an array of generated TypeScript type lines.
|
|
114
115
|
*/
|
|
115
|
-
export async function generateTypes(
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
export async function generateTypes(
|
|
117
|
+
inputData: InputData,
|
|
118
|
+
opts: GenerateOptions,
|
|
119
|
+
): Promise<string[]> {
|
|
118
120
|
// Generate the types
|
|
119
121
|
const out = await quicktype({
|
|
120
122
|
inputData,
|
|
121
|
-
lang:
|
|
123
|
+
lang: opts.language,
|
|
122
124
|
rendererOptions: { "just-types": "true" },
|
|
123
125
|
});
|
|
124
126
|
|