kubernetes-fluent-client 3.5.5 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +9 -16
- package/dist/fetch.js +5 -8
- package/dist/fluent/index.d.ts +2 -1
- package/dist/fluent/index.d.ts.map +1 -1
- package/dist/fluent/index.js +27 -29
- package/dist/fluent/shared-types.d.ts +49 -0
- package/dist/fluent/shared-types.d.ts.map +1 -0
- package/dist/fluent/shared-types.js +23 -0
- package/dist/fluent/types.d.ts +2 -37
- package/dist/fluent/types.d.ts.map +1 -1
- package/dist/fluent/types.js +1 -14
- package/dist/fluent/utils.d.ts +1 -1
- package/dist/fluent/utils.d.ts.map +1 -1
- package/dist/fluent/utils.js +25 -35
- package/dist/fluent/watch.d.ts +1 -8
- package/dist/fluent/watch.d.ts.map +1 -1
- package/dist/fluent/watch.js +23 -43
- package/dist/generate.js +22 -65
- package/dist/helpers.js +5 -10
- package/dist/index.js +13 -60
- package/dist/kinds.js +2 -7
- package/dist/normalization.d.ts +97 -0
- package/dist/normalization.d.ts.map +1 -0
- package/dist/normalization.js +152 -0
- package/dist/patch.js +1 -2
- package/dist/postProcessing.d.ts +6 -127
- package/dist/postProcessing.d.ts.map +1 -1
- package/dist/postProcessing.js +24 -279
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -5
- package/dist/upstream.js +2 -53
- package/package.json +15 -12
- package/src/cli.ts +1 -3
- package/src/fluent/index.ts +12 -11
- package/src/fluent/shared-types.ts +55 -0
- package/src/fluent/types.ts +3 -54
- package/src/fluent/utils.ts +2 -2
- package/src/fluent/watch.ts +2 -21
- package/src/normalization.ts +181 -0
- package/src/postProcessing.ts +11 -239
- package/src/types.ts +3 -4
- package/dist/fileSystem.d.ts +0 -11
- package/dist/fileSystem.d.ts.map +0 -1
- package/dist/fileSystem.js +0 -52
- package/src/fileSystem.ts +0 -25
package/src/fluent/index.ts
CHANGED
|
@@ -9,7 +9,8 @@ import type { PartialDeep } from "type-fest";
|
|
|
9
9
|
import { fetch } from "../fetch";
|
|
10
10
|
import { modelToGroupVersionKind } from "../kinds";
|
|
11
11
|
import { GenericClass } from "../types";
|
|
12
|
-
import {
|
|
12
|
+
import { K8sInit, Paths } from "./types";
|
|
13
|
+
import { Filters, WatchAction, FetchMethods, ApplyCfg } from "./shared-types";
|
|
13
14
|
import { k8sCfg, k8sExec } from "./utils";
|
|
14
15
|
import { WatchCfg, Watcher } from "./watch";
|
|
15
16
|
import { hasLogs } from "../helpers";
|
|
@@ -114,7 +115,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
try {
|
|
117
|
-
const object = await k8sExec<T, K>(model, filters,
|
|
118
|
+
const object = await k8sExec<T, K>(model, filters, FetchMethods.GET);
|
|
118
119
|
|
|
119
120
|
if (kind !== "Pod") {
|
|
120
121
|
if (kind === "Service") {
|
|
@@ -144,7 +145,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
144
145
|
|
|
145
146
|
const podModel = { ...model, name: "V1Pod" };
|
|
146
147
|
const logPromises = podList.map(po =>
|
|
147
|
-
k8sExec<T, string>(podModel, { ...filters, name: po.metadata!.name! },
|
|
148
|
+
k8sExec<T, string>(podModel, { ...filters, name: po.metadata!.name! }, FetchMethods.LOG),
|
|
148
149
|
);
|
|
149
150
|
|
|
150
151
|
const responses = await Promise.all(logPromises);
|
|
@@ -179,7 +180,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
179
180
|
filters.name = name;
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
return k8sExec<T, K | KubernetesListObject<K>>(model, filters,
|
|
183
|
+
return k8sExec<T, K | KubernetesListObject<K>>(model, filters, FetchMethods.GET);
|
|
183
184
|
}
|
|
184
185
|
|
|
185
186
|
/**
|
|
@@ -195,7 +196,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
195
196
|
|
|
196
197
|
try {
|
|
197
198
|
// Try to delete the resource
|
|
198
|
-
await k8sExec<T, void>(model, filters,
|
|
199
|
+
await k8sExec<T, void>(model, filters, FetchMethods.DELETE);
|
|
199
200
|
} catch (e) {
|
|
200
201
|
// If the resource doesn't exist, ignore the error
|
|
201
202
|
if (e.status === StatusCodes.NOT_FOUND) {
|
|
@@ -215,7 +216,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
215
216
|
applyCfg: ApplyCfg = { force: false },
|
|
216
217
|
): Promise<K> {
|
|
217
218
|
syncFilters(resource as K);
|
|
218
|
-
return k8sExec(model, filters,
|
|
219
|
+
return k8sExec(model, filters, FetchMethods.APPLY, resource, applyCfg);
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
/**
|
|
@@ -224,7 +225,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
224
225
|
*/
|
|
225
226
|
async function Create(resource: K): Promise<K> {
|
|
226
227
|
syncFilters(resource);
|
|
227
|
-
return k8sExec(model, filters,
|
|
228
|
+
return k8sExec(model, filters, FetchMethods.POST, resource);
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
/**
|
|
@@ -248,7 +249,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
248
249
|
},
|
|
249
250
|
};
|
|
250
251
|
// Try to evict the resource
|
|
251
|
-
await k8sExec<T, void>(model, filters,
|
|
252
|
+
await k8sExec<T, void>(model, filters, FetchMethods.POST, evictionPayload);
|
|
252
253
|
} catch (e) {
|
|
253
254
|
// If the resource doesn't exist, ignore the error
|
|
254
255
|
if (e.status === StatusCodes.NOT_FOUND) {
|
|
@@ -268,7 +269,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
268
269
|
throw new Error("No operations specified");
|
|
269
270
|
}
|
|
270
271
|
|
|
271
|
-
return k8sExec(model, filters,
|
|
272
|
+
return k8sExec(model, filters, FetchMethods.PATCH, payload);
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
/**
|
|
@@ -277,7 +278,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
277
278
|
*/
|
|
278
279
|
async function PatchStatus(resource: PartialDeep<K>): Promise<K> {
|
|
279
280
|
syncFilters(resource as K);
|
|
280
|
-
return k8sExec(model, filters,
|
|
281
|
+
return k8sExec(model, filters, FetchMethods.PATCH_STATUS, resource);
|
|
281
282
|
}
|
|
282
283
|
|
|
283
284
|
/**
|
|
@@ -292,7 +293,7 @@ export function K8s<T extends GenericClass, K extends KubernetesObject = Instanc
|
|
|
292
293
|
* @inheritdoc
|
|
293
294
|
* @see {@link K8sInit.Raw}
|
|
294
295
|
*/
|
|
295
|
-
async function Raw(url: string, method: FetchMethods =
|
|
296
|
+
async function Raw(url: string, method: FetchMethods = FetchMethods.GET) {
|
|
296
297
|
const thing = await k8sCfg(method);
|
|
297
298
|
const { opts, serverUrl } = thing;
|
|
298
299
|
const resp = await fetch<K>(`${serverUrl}${url}`, opts);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
|
|
3
|
+
import { GenericClass, GroupVersionKind } from "../types";
|
|
4
|
+
import { RequestInit } from "undici";
|
|
5
|
+
import { KubernetesObject } from "@kubernetes/client-node";
|
|
6
|
+
/**
|
|
7
|
+
* Fetch options and server URL
|
|
8
|
+
*/
|
|
9
|
+
export type K8sConfigPromise = Promise<{ opts: RequestInit; serverUrl: string | URL }>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The Phase matched when using the K8s Watch API.
|
|
13
|
+
*/
|
|
14
|
+
export enum WatchPhase {
|
|
15
|
+
Added = "ADDED",
|
|
16
|
+
Modified = "MODIFIED",
|
|
17
|
+
Deleted = "DELETED",
|
|
18
|
+
Bookmark = "BOOKMARK",
|
|
19
|
+
Error = "ERROR",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type WatchAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
|
|
23
|
+
update: K,
|
|
24
|
+
phase: WatchPhase,
|
|
25
|
+
) => Promise<void> | void;
|
|
26
|
+
|
|
27
|
+
export interface Filters {
|
|
28
|
+
kindOverride?: GroupVersionKind;
|
|
29
|
+
fields?: Record<string, string>;
|
|
30
|
+
labels?: Record<string, string>;
|
|
31
|
+
name?: string;
|
|
32
|
+
namespace?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Configuration for the apply function.
|
|
37
|
+
*/
|
|
38
|
+
export type ApplyCfg = {
|
|
39
|
+
/**
|
|
40
|
+
* Force the apply to be a create.
|
|
41
|
+
*/
|
|
42
|
+
force?: boolean;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export enum FetchMethods {
|
|
46
|
+
APPLY = "APPLY",
|
|
47
|
+
DELETE = "DELETE",
|
|
48
|
+
GET = "GET",
|
|
49
|
+
LOG = "LOG",
|
|
50
|
+
PATCH = "PATCH",
|
|
51
|
+
PATCH_STATUS = "PATCH_STATUS",
|
|
52
|
+
POST = "POST",
|
|
53
|
+
PUT = "PUT",
|
|
54
|
+
WATCH = "WATCH",
|
|
55
|
+
}
|
package/src/fluent/types.ts
CHANGED
|
@@ -4,22 +4,16 @@
|
|
|
4
4
|
import { KubernetesListObject, KubernetesObject } from "@kubernetes/client-node";
|
|
5
5
|
import { Operation } from "fast-json-patch";
|
|
6
6
|
import type { PartialDeep } from "type-fest";
|
|
7
|
-
import {
|
|
8
|
-
import { GenericClass, GroupVersionKind } from "../types";
|
|
7
|
+
import { GenericClass } from "../types";
|
|
9
8
|
import { WatchCfg, Watcher } from "./watch";
|
|
10
9
|
import https from "https";
|
|
11
10
|
import { SecureClientSessionOptions } from "http2";
|
|
12
|
-
|
|
11
|
+
import { WatchAction, FetchMethods, ApplyCfg } from "./shared-types";
|
|
13
12
|
/*
|
|
14
|
-
* Watch Class Type
|
|
13
|
+
* Watch Class Type - Used in Pepr Watch Processor
|
|
15
14
|
*/
|
|
16
15
|
export type WatcherType<T extends GenericClass> = Watcher<T>;
|
|
17
16
|
|
|
18
|
-
/**
|
|
19
|
-
* Fetch options and server URL
|
|
20
|
-
*/
|
|
21
|
-
export type K8sConfigPromise = Promise<{ opts: RequestInit; serverUrl: string | URL }>;
|
|
22
|
-
|
|
23
17
|
/**
|
|
24
18
|
* Agent options for the the http2Watch
|
|
25
19
|
*/
|
|
@@ -35,36 +29,6 @@ export interface Options {
|
|
|
35
29
|
agent?: https.Agent & { options?: AgentOptions };
|
|
36
30
|
}
|
|
37
31
|
|
|
38
|
-
/**
|
|
39
|
-
* The Phase matched when using the K8s Watch API.
|
|
40
|
-
*/
|
|
41
|
-
export enum WatchPhase {
|
|
42
|
-
Added = "ADDED",
|
|
43
|
-
Modified = "MODIFIED",
|
|
44
|
-
Deleted = "DELETED",
|
|
45
|
-
Bookmark = "BOOKMARK",
|
|
46
|
-
Error = "ERROR",
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export type FetchMethods =
|
|
50
|
-
| "APPLY"
|
|
51
|
-
| "DELETE"
|
|
52
|
-
| "GET"
|
|
53
|
-
| "LOG"
|
|
54
|
-
| "PATCH"
|
|
55
|
-
| "PATCH_STATUS"
|
|
56
|
-
| "POST"
|
|
57
|
-
| "PUT"
|
|
58
|
-
| "WATCH";
|
|
59
|
-
|
|
60
|
-
export interface Filters {
|
|
61
|
-
kindOverride?: GroupVersionKind;
|
|
62
|
-
fields?: Record<string, string>;
|
|
63
|
-
labels?: Record<string, string>;
|
|
64
|
-
name?: string;
|
|
65
|
-
namespace?: string;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
32
|
/**
|
|
69
33
|
* Get the resource or resources matching the filters.
|
|
70
34
|
* If no filters are specified, all resources will be returned.
|
|
@@ -225,16 +189,6 @@ export type K8sWithFilters<T extends GenericClass, K extends KubernetesObject> =
|
|
|
225
189
|
WithLabel: (key: string, value?: string) => K8sWithFilters<T, K>;
|
|
226
190
|
};
|
|
227
191
|
|
|
228
|
-
/**
|
|
229
|
-
* Configuration for the apply function.
|
|
230
|
-
*/
|
|
231
|
-
export type ApplyCfg = {
|
|
232
|
-
/**
|
|
233
|
-
* Force the apply to be a create.
|
|
234
|
-
*/
|
|
235
|
-
force?: boolean;
|
|
236
|
-
};
|
|
237
|
-
|
|
238
192
|
export type K8sInit<T extends GenericClass, K extends KubernetesObject> = K8sWithFilters<T, K> &
|
|
239
193
|
K8sUnfilteredActions<K> & {
|
|
240
194
|
/**
|
|
@@ -246,11 +200,6 @@ export type K8sInit<T extends GenericClass, K extends KubernetesObject> = K8sWit
|
|
|
246
200
|
InNamespace: (namespace: string) => K8sWithFilters<T, K>;
|
|
247
201
|
};
|
|
248
202
|
|
|
249
|
-
export type WatchAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
|
|
250
|
-
update: K,
|
|
251
|
-
phase: WatchPhase,
|
|
252
|
-
) => Promise<void> | void;
|
|
253
|
-
|
|
254
203
|
// Special types to handle the recursive keyof typescript lookup
|
|
255
204
|
type Join<K, P> = K extends string | number
|
|
256
205
|
? P extends string | number
|
package/src/fluent/utils.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { Agent as httpsAgent } from "https";
|
|
|
9
9
|
import { fetch } from "../fetch";
|
|
10
10
|
import { modelToGroupVersionKind } from "../kinds";
|
|
11
11
|
import { GenericClass } from "../types";
|
|
12
|
-
import { ApplyCfg,
|
|
12
|
+
import { ApplyCfg, Filters, K8sConfigPromise, FetchMethods } from "./shared-types";
|
|
13
13
|
import fs from "fs";
|
|
14
14
|
import { V1Eviction as Eviction } from "@kubernetes/client-node";
|
|
15
15
|
const SSA_CONTENT_TYPE = "application/apply-patch+yaml";
|
|
@@ -222,7 +222,7 @@ export async function k8sExec<T extends GenericClass, K>(
|
|
|
222
222
|
applyCfg: ApplyCfg = { force: false },
|
|
223
223
|
) {
|
|
224
224
|
const reconstruct = async (method: FetchMethods): K8sConfigPromise => {
|
|
225
|
-
const configMethod = method ===
|
|
225
|
+
const configMethod = method === FetchMethods.LOG ? FetchMethods.GET : method;
|
|
226
226
|
const { opts, serverUrl } = await k8sCfg(configMethod);
|
|
227
227
|
|
|
228
228
|
// Build the base path once, using excludeName only for standard POST requests
|
package/src/fluent/watch.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
|
|
3
3
|
|
|
4
|
-
import { createHash } from "crypto";
|
|
5
4
|
import { EventEmitter } from "events";
|
|
6
5
|
import { fetch } from "undici";
|
|
7
6
|
import { fetch as wrappedFetch } from "../fetch";
|
|
8
7
|
import { GenericClass, KubernetesListObject } from "../types";
|
|
9
|
-
import { Filters, WatchAction, WatchPhase, K8sConfigPromise } from "./types";
|
|
10
8
|
import { k8sCfg, pathBuilder, getHeaders } from "./utils";
|
|
11
9
|
import { Readable } from "stream";
|
|
12
|
-
|
|
10
|
+
import { K8sConfigPromise, WatchPhase, WatchAction, Filters, FetchMethods } from "./shared-types";
|
|
13
11
|
export enum WatchEvent {
|
|
14
12
|
/** Watch is connected successfully */
|
|
15
13
|
CONNECT = "connect",
|
|
@@ -171,23 +169,6 @@ export class Watcher<T extends GenericClass> {
|
|
|
171
169
|
this.#abortController.abort();
|
|
172
170
|
}
|
|
173
171
|
|
|
174
|
-
/**
|
|
175
|
-
* Get a unique ID for the watch based on the model and filters.
|
|
176
|
-
* This is useful for caching the watch data or resource versions.
|
|
177
|
-
*
|
|
178
|
-
* @returns the watch CacheID
|
|
179
|
-
*/
|
|
180
|
-
public getCacheID() {
|
|
181
|
-
// Build the URL, we don't care about the server URL or resourceVersion
|
|
182
|
-
const url = pathBuilder("https://ignore", this.#model, this.#filters, false);
|
|
183
|
-
|
|
184
|
-
// Hash and truncate the ID to 10 characters, cache the result
|
|
185
|
-
return createHash("sha224")
|
|
186
|
-
.update(url.pathname + url.search)
|
|
187
|
-
.digest("hex")
|
|
188
|
-
.substring(0, 10);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
172
|
/**
|
|
192
173
|
* Subscribe to watch events. This is an EventEmitter that emits the following events:
|
|
193
174
|
*
|
|
@@ -214,7 +195,7 @@ export class Watcher<T extends GenericClass> {
|
|
|
214
195
|
continueToken?: string,
|
|
215
196
|
): K8sConfigPromise => {
|
|
216
197
|
// Build the path and query params for the resource, excluding the name
|
|
217
|
-
const { opts, serverUrl } = await k8sCfg(
|
|
198
|
+
const { opts, serverUrl } = await k8sCfg(FetchMethods.GET);
|
|
218
199
|
const k8sUrl = serverUrl instanceof URL ? serverUrl.toString() : serverUrl;
|
|
219
200
|
const url = pathBuilder(k8sUrl, this.#model, this.#filters, true);
|
|
220
201
|
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { GenerateOptions } from "./generate";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes indentation for TypeScript lines to a consistent format.
|
|
5
|
+
*
|
|
6
|
+
* @param lines The generated TypeScript lines.
|
|
7
|
+
* @returns The lines with normalized indentation.
|
|
8
|
+
*/
|
|
9
|
+
export function normalizeIndentation(lines: string[]): string[] {
|
|
10
|
+
return lines.map(line => line.replace(/^ {4}/, " "));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Normalizes the indentation of a single line to use two spaces instead of four.
|
|
15
|
+
*
|
|
16
|
+
* @param line The line of code to normalize.
|
|
17
|
+
* @returns The line with normalized indentation.
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeLineIndentation(line: string): string {
|
|
20
|
+
return line.replace(/^ {4}/, " ");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Normalizes spacing between property names and types in TypeScript lines.
|
|
25
|
+
*
|
|
26
|
+
* @param lines The generated TypeScript lines.
|
|
27
|
+
* @returns The lines with normalized property spacing.
|
|
28
|
+
*/
|
|
29
|
+
export function normalizePropertySpacing(lines: string[]): string[] {
|
|
30
|
+
// https://regex101.com/r/XEv3pL/1
|
|
31
|
+
return lines.map(line => line.replace(/\s*\?\s*:\s*/, "?: "));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Processes a single line inside a class extending `GenericKind`.
|
|
36
|
+
*
|
|
37
|
+
* @param line The current line of code.
|
|
38
|
+
* @param genericKindProperties The list of properties from `GenericKind`.
|
|
39
|
+
* @param foundInterfaces The set of found interfaces in the file.
|
|
40
|
+
* @returns The modified line.
|
|
41
|
+
*/
|
|
42
|
+
export function modifyAndNormalizeClassProperties(
|
|
43
|
+
line: string,
|
|
44
|
+
genericKindProperties: string[],
|
|
45
|
+
foundInterfaces: Set<string>,
|
|
46
|
+
): string {
|
|
47
|
+
line = modifyPropertiesAndAddEslintDirective(line, genericKindProperties, foundInterfaces);
|
|
48
|
+
line = normalizeLineIndentation(line);
|
|
49
|
+
return line;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Normalizes lines after processing, including indentation, spacing, and removing unnecessary lines.
|
|
54
|
+
*
|
|
55
|
+
* @param lines The lines of the file content.
|
|
56
|
+
* @param opts The options for processing.
|
|
57
|
+
* @returns The normalized lines.
|
|
58
|
+
*/
|
|
59
|
+
export function normalizeIndentationAndSpacing(lines: string[], opts: GenerateOptions): string[] {
|
|
60
|
+
let normalizedLines = normalizeIndentation(lines);
|
|
61
|
+
normalizedLines = normalizePropertySpacing(normalizedLines);
|
|
62
|
+
return removePropertyStringAny(normalizedLines, opts);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Removes lines containing `[property: string]: any;` from TypeScript files.
|
|
67
|
+
*
|
|
68
|
+
* @param lines The generated TypeScript lines.
|
|
69
|
+
* @param opts The options for processing.
|
|
70
|
+
* @returns The lines with `[property: string]: any;` removed.
|
|
71
|
+
*/
|
|
72
|
+
export function removePropertyStringAny(lines: string[], opts: GenerateOptions): string[] {
|
|
73
|
+
if (opts.language === "ts" || opts.language === "typescript") {
|
|
74
|
+
return lines.filter(line => !line.includes("[property: string]: any;"));
|
|
75
|
+
}
|
|
76
|
+
return lines;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Applies ESLint and property modifiers to a line of code.
|
|
81
|
+
*
|
|
82
|
+
* @param line - The current line of code.
|
|
83
|
+
* @param genericKindProperties - The list of properties from `GenericKind`.
|
|
84
|
+
* @param foundInterfaces - The set of found interfaces in the file.
|
|
85
|
+
* @returns The modified line.
|
|
86
|
+
*/
|
|
87
|
+
export function modifyPropertiesAndAddEslintDirective(
|
|
88
|
+
line: string,
|
|
89
|
+
genericKindProperties: string[],
|
|
90
|
+
foundInterfaces: Set<string>,
|
|
91
|
+
): string {
|
|
92
|
+
line = addDeclareAndOptionalModifiersToProperties(line, genericKindProperties, foundInterfaces);
|
|
93
|
+
line = processEslintDisable(line, genericKindProperties);
|
|
94
|
+
return line;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Adds an ESLint disable comment for `[key: string]: any` if it's not part of `GenericKind`.
|
|
99
|
+
*
|
|
100
|
+
* @param line The current line of code.
|
|
101
|
+
* @param genericKindProperties The list of properties from `GenericKind`.
|
|
102
|
+
* @returns The modified line with the ESLint disable comment.
|
|
103
|
+
*/
|
|
104
|
+
export function processEslintDisable(line: string, genericKindProperties: string[]): string {
|
|
105
|
+
if (line.includes("[key: string]: any") && !genericKindProperties.includes("[key: string]")) {
|
|
106
|
+
return ` // eslint-disable-next-line @typescript-eslint/no-explicit-any\n${line}`;
|
|
107
|
+
}
|
|
108
|
+
return line;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Applies property modifiers to a line of code.
|
|
113
|
+
*
|
|
114
|
+
* @param line The current line of code.
|
|
115
|
+
* @param genericKindProperties The list of properties from `GenericKind`.
|
|
116
|
+
* @param foundInterfaces The set of found interfaces in the file.
|
|
117
|
+
* @returns The modified line.
|
|
118
|
+
*/
|
|
119
|
+
export function addDeclareAndOptionalModifiersToProperties(
|
|
120
|
+
line: string,
|
|
121
|
+
genericKindProperties: string[],
|
|
122
|
+
foundInterfaces: Set<string>,
|
|
123
|
+
): string {
|
|
124
|
+
line = addDeclareToGenericKindProperties(line, genericKindProperties);
|
|
125
|
+
line = makePropertiesOptional(line, foundInterfaces);
|
|
126
|
+
line = normalizeLineIndentation(line);
|
|
127
|
+
return line;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Adds the `declare` keyword to `GenericKind` properties.
|
|
132
|
+
*
|
|
133
|
+
* @param line The current line of code.
|
|
134
|
+
* @param genericKindProperties The list of properties from `GenericKind`.
|
|
135
|
+
* @returns The modified line with the `declare` keyword, if applicable.
|
|
136
|
+
*/
|
|
137
|
+
export function addDeclareToGenericKindProperties(
|
|
138
|
+
line: string,
|
|
139
|
+
genericKindProperties: string[],
|
|
140
|
+
): string {
|
|
141
|
+
for (const prop of genericKindProperties) {
|
|
142
|
+
const propertyPattern = getPropertyPattern(prop);
|
|
143
|
+
if (propertyPattern.test(line)) {
|
|
144
|
+
return line.replace(prop, `declare ${prop}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return line;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Makes a property optional if its type matches one of the found interfaces and it is not already optional.
|
|
152
|
+
*
|
|
153
|
+
* @param line The current line of code.
|
|
154
|
+
* @param foundInterfaces The set of found interfaces in the file.
|
|
155
|
+
* @returns The modified line with the optional `?` symbol.
|
|
156
|
+
*/
|
|
157
|
+
export function makePropertiesOptional(line: string, foundInterfaces: Set<string>): string {
|
|
158
|
+
// https://regex101.com/r/kX8TCj/1
|
|
159
|
+
const propertyTypePattern = /:\s*(?<propertyType>\w+)\s*;/;
|
|
160
|
+
const match = line.match(propertyTypePattern);
|
|
161
|
+
|
|
162
|
+
if (match?.groups?.propertyType) {
|
|
163
|
+
const { propertyType } = match.groups;
|
|
164
|
+
if (foundInterfaces.has(propertyType) && !line.includes("?")) {
|
|
165
|
+
return line.replace(":", "?:");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return line;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Generates a regular expression to match a property pattern in TypeScript.
|
|
173
|
+
*
|
|
174
|
+
* @param prop The property name to match.
|
|
175
|
+
* @returns A regular expression to match the property pattern.
|
|
176
|
+
*/
|
|
177
|
+
export function getPropertyPattern(prop: string): RegExp {
|
|
178
|
+
// For prop="kind", the pattern will match "kind ? :" or "kind :"
|
|
179
|
+
// https://regex101.com/r/mF8kXn/1
|
|
180
|
+
return new RegExp(`\\b${prop}\\b\\s*\\?\\s*:|\\b${prop}\\b\\s*:`);
|
|
181
|
+
}
|