@hyper-fetch/cli 7.5.2 → 7.5.3

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.
@@ -0,0 +1,366 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ /**
3
+ * @jest-environment node
4
+ */
5
+
6
+ import { promises as fsPromises } from "fs";
7
+ import * as path from "path";
8
+ import * as fs from "fs-extra";
9
+
10
+ import { OpenapiRequestGenerator, Document, getAvailableOperations, Operation } from "codegen/openapi";
11
+ import { HttpMethod } from "codegen/openapi/http-methods.enum";
12
+
13
+ const expectedMetadata = {
14
+ findPets: {
15
+ id: "findPets",
16
+ pathParametersType: undefined,
17
+ queryParametersType: "Paths.FindPets.QueryParameters",
18
+ requestBodyType: undefined,
19
+ responseType: "Paths.FindPets.Responses.$200",
20
+ path: "/pets",
21
+ method: "GET",
22
+ },
23
+ addPet: {
24
+ id: "addPet",
25
+ pathParametersType: undefined,
26
+ queryParametersType: undefined,
27
+ requestBodyType: "Paths.AddPet.RequestBody",
28
+ responseType: "Paths.AddPet.Responses.$200",
29
+ path: "/pet",
30
+ method: "POST",
31
+ },
32
+ find_pet_by_id: {
33
+ id: "find_pet_by_id",
34
+ pathParametersType: "Paths.FindPetById.PathParameters",
35
+ queryParametersType: undefined,
36
+ requestBodyType: undefined,
37
+ responseType: "Paths.FindPetById.Responses.$200",
38
+ path: "/pet/:id",
39
+ method: "GET",
40
+ },
41
+ deletePet: {
42
+ id: "deletePet",
43
+ pathParametersType: "Paths.DeletePet.PathParameters",
44
+ queryParametersType: undefined,
45
+ requestBodyType: undefined,
46
+ responseType: "any",
47
+ path: "/pet/:petId",
48
+ method: "DELETE",
49
+ },
50
+ updatePet: {
51
+ id: "updatePet",
52
+ pathParametersType: undefined,
53
+ queryParametersType: undefined,
54
+ requestBodyType: "Paths.UpdatePet.RequestBody",
55
+ responseType: "Paths.UpdatePet.Responses.$200",
56
+ path: "/pet",
57
+ method: "PUT",
58
+ },
59
+ };
60
+ const expectedOperationTypes = {
61
+ FindPetsQueryParams: "export type FindPetsQueryParams = Paths.FindPets.QueryParameters",
62
+ FindPetsResponseType: "export type FindPetsResponseType = Paths.FindPets.Responses.$200",
63
+ AddPetRequestBody: "export type AddPetRequestBody = Paths.AddPet.RequestBody",
64
+ AddPetResponseType: "export type AddPetResponseType = Paths.AddPet.Responses.$200",
65
+ AddPetErrorType: "export type AddPetErrorType = Paths.AddPet.Responses.$405",
66
+ FindPetByIdPathParams: "export type FindPetByIdPathParams = Paths.FindPetById.PathParameters",
67
+ FindPetByIdResponseType: "export type FindPetByIdResponseType = Paths.FindPetById.Responses.$200",
68
+ DeletePetPathParams: "export type DeletePetPathParams = Paths.DeletePet.PathParameters",
69
+ DeletePetResponseType: "export type DeletePetResponseType = any",
70
+ DeletePetErrorType: "export type DeletePetErrorType = Paths.DeletePet.Responses.$400",
71
+ UpdatePetRequestBody: "export type UpdatePetRequestBody = Paths.UpdatePet.RequestBody",
72
+ UpdatePetResponseType: "export type UpdatePetResponseType = Paths.UpdatePet.Responses.$200",
73
+ UpdatePetErrorType:
74
+ "export type UpdatePetErrorType = Paths.UpdatePet.Responses.$400 | Paths.UpdatePet.Responses.$404 | Paths.UpdatePet.Responses.$405",
75
+ };
76
+ const expectedRequests = [
77
+ `export const findPets = client.createRequest<{response:FindPetsResponseType,queryParams?:FindPetsQueryParams}>()({method: "GET", endpoint: "/pets"})`,
78
+ `export const addPet = client.createRequest<{response:AddPetResponseType,payload:AddPetRequestBody,error:AddPetErrorType}>()({method: "POST", endpoint: "/pet"})`,
79
+ `export const deletePet = client.createRequest<{response:DeletePetResponseType,error:DeletePetErrorType}>()({method: "DELETE", endpoint: "/pet/:petId"})`,
80
+ `export const updatePet = client.createRequest<{response:UpdatePetResponseType,payload:UpdatePetRequestBody,error:UpdatePetErrorType}>()({method: "PUT", endpoint: "/pet"})`,
81
+ ];
82
+
83
+ describe("Generator", () => {
84
+ let schema: string;
85
+
86
+ beforeAll(async () => {
87
+ const file = await fsPromises.readFile(path.resolve(__dirname, "../schemas/v3/petstore-expanded.json"), "utf8");
88
+ schema = JSON.parse(file);
89
+
90
+ // Ensure the directory exists before writing the file
91
+ await fs.ensureDir(path.join(__dirname, "../__temp__"));
92
+ });
93
+
94
+ it("should generate hyper fetch requests", async () => {
95
+ const { exportedTypes } = await OpenapiRequestGenerator.prepareSchema(schema as unknown as Document);
96
+ getAvailableOperations(schema as unknown as Document).forEach((operation) => {
97
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
98
+ const operationTypes = OpenapiRequestGenerator.generateTypes(meta);
99
+ const generatedRequest = OpenapiRequestGenerator.generateHyperFetchRequest(meta, operationTypes);
100
+
101
+ if (expectedMetadata[meta.id as keyof typeof expectedMetadata]) {
102
+ expect(meta).toMatchObject(expectedMetadata[meta.id as keyof typeof expectedMetadata]);
103
+
104
+ Object.entries(operationTypes).forEach(([name, value]) => {
105
+ expect(value).toStrictEqual(expectedOperationTypes[name as keyof typeof expectedOperationTypes]);
106
+ });
107
+ expect(expectedRequests).toContain(generatedRequest);
108
+ }
109
+ });
110
+ });
111
+
112
+ it("Should generate file with default name", async () => {
113
+ const generator = new OpenapiRequestGenerator(schema);
114
+ const generatedFileNamePath = await generator.generateFile({
115
+ config: {
116
+ tsx: true,
117
+ aliases: { api: "api", hooks: "hooks", ui: "ui", components: "components", lib: "lib" },
118
+ resolvedPaths: {
119
+ cwd: __dirname,
120
+ api: path.join(__dirname, "../__temp__"),
121
+ hooks: path.join(__dirname, "hooks"),
122
+ ui: path.join(__dirname, "ui"),
123
+ components: path.join(__dirname, "components"),
124
+ lib: path.join(__dirname, "lib"),
125
+ },
126
+ },
127
+ fileName: "openapi.client",
128
+ });
129
+ expect(generatedFileNamePath).toEndWith("openapi.client.ts");
130
+ });
131
+
132
+ it("Should generate file with js extension", async () => {
133
+ const generator = new OpenapiRequestGenerator(schema);
134
+ const generatedFileNamePath = await generator.generateFile({
135
+ config: {
136
+ tsx: false,
137
+ aliases: { api: "api", hooks: "hooks", ui: "ui", components: "components", lib: "lib" },
138
+ resolvedPaths: {
139
+ cwd: __dirname,
140
+ api: path.join(__dirname, "../__temp__"),
141
+ hooks: path.join(__dirname, "hooks"),
142
+ ui: path.join(__dirname, "ui"),
143
+ components: path.join(__dirname, "components"),
144
+ lib: path.join(__dirname, "lib"),
145
+ },
146
+ },
147
+ fileName: "openapi.client",
148
+ });
149
+ expect(generatedFileNamePath).toEndWith("openapi.client.js");
150
+ });
151
+
152
+ it("Should generate file with provided name", async () => {
153
+ const generator = new OpenapiRequestGenerator(schema);
154
+ const generatedFileNamePath = await generator.generateFile({
155
+ config: {
156
+ tsx: true,
157
+ aliases: { api: "api", hooks: "hooks", ui: "ui", components: "components", lib: "lib" },
158
+ resolvedPaths: {
159
+ cwd: __dirname,
160
+ api: path.join(__dirname, "../__temp__"),
161
+ hooks: path.join(__dirname, "hooks"),
162
+ ui: path.join(__dirname, "ui"),
163
+ components: path.join(__dirname, "components"),
164
+ lib: path.join(__dirname, "lib"),
165
+ },
166
+ },
167
+ fileName: "schemaApiRequests",
168
+ });
169
+ expect(generatedFileNamePath).toEndWith("schemaApiRequests.ts");
170
+ });
171
+
172
+ it("Should generate file with provided name without duplication for .ts ending if provided", async () => {
173
+ const generator = new OpenapiRequestGenerator(schema);
174
+ const generatedFileNamePath = await generator.generateFile({
175
+ config: {
176
+ tsx: true,
177
+ aliases: { api: "api", hooks: "hooks", ui: "ui", components: "components", lib: "lib" },
178
+ resolvedPaths: {
179
+ cwd: __dirname,
180
+ api: path.join(__dirname, "../__temp__"),
181
+ hooks: path.join(__dirname, "hooks"),
182
+ ui: path.join(__dirname, "ui"),
183
+ components: path.join(__dirname, "components"),
184
+ lib: path.join(__dirname, "lib"),
185
+ },
186
+ },
187
+ fileName: "schemaApiRequests.ts",
188
+ });
189
+ expect(generatedFileNamePath).toEndWith("schemaApiRequests.ts");
190
+ });
191
+
192
+ // it("Should generate file with provided baseUrl", async () => {
193
+ // const baseUrl = "http://baseurl.com";
194
+ // const generator = new OpenapiRequestGenerator(schema);
195
+ // const generatedFileNamePath = await generator.generateFile({ url: "http://baseurl.com" });
196
+ // const imported = await import(generatedFileNamePath);
197
+ // expect(imported.client.url).toEqual(baseUrl);
198
+ //
199
+ // });
200
+
201
+ describe("HTTP Method handling", () => {
202
+ it("should use provided HTTP method in uppercase", async () => {
203
+ const { exportedTypes } = await OpenapiRequestGenerator.prepareSchema(schema as unknown as Document);
204
+ const operations = getAvailableOperations(schema as unknown as Document);
205
+
206
+ // Find the POST operation (addPet)
207
+ const postOperation = operations.find((op) => op.method === "post");
208
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(postOperation!, exportedTypes);
209
+
210
+ expect(meta.method).toBe("POST");
211
+ });
212
+
213
+ it("should default to GET when no method is provided", async () => {
214
+ const { exportedTypes } = await OpenapiRequestGenerator.prepareSchema(schema as unknown as Document);
215
+ const operation = {
216
+ // Minimal operation object without method
217
+ operationId: "testOperation",
218
+ path: "/test",
219
+ method: undefined as any,
220
+ };
221
+
222
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
223
+
224
+ expect(meta.method).toBe("get");
225
+ });
226
+ });
227
+
228
+ describe("Error type handling", () => {
229
+ let exportedTypes: any;
230
+
231
+ beforeEach(async () => {
232
+ exportedTypes = (await OpenapiRequestGenerator.prepareSchema(schema as unknown as Document)).exportedTypes;
233
+ });
234
+
235
+ it("should generate both error and response types when both are present", async () => {
236
+ const operation: { operationId: string; path: string; method: string } & Partial<Operation> = {
237
+ operationId: "testOperation",
238
+ path: "/test",
239
+ method: HttpMethod.GET,
240
+
241
+ responses: {
242
+ "200": { content: { "application/json": { schema: { type: "object" } } }, description: "" },
243
+ "400": { content: { "application/json": { schema: { type: "object" } } }, description: "" },
244
+ },
245
+ };
246
+
247
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
248
+ meta.errorType = "ErrorType";
249
+ meta.responseType = "ResponseType";
250
+
251
+ const types = OpenapiRequestGenerator.generateTypes(meta);
252
+
253
+ // Verify exact type strings are generated
254
+ expect(types.TestOperationErrorType).toBe("export type TestOperationErrorType = ErrorType");
255
+ expect(types.TestOperationResponseType).toBe("export type TestOperationResponseType = ResponseType");
256
+ });
257
+
258
+ it("should generate only response type when error type is null", async () => {
259
+ const operation: { operationId: string; path: string; method: string } & Partial<Operation> = {
260
+ operationId: "testOperation",
261
+ path: "/test",
262
+ method: HttpMethod.GET,
263
+ responses: {
264
+ "200": { content: { "application/json": { schema: { type: "object" } } }, description: "" },
265
+ },
266
+ };
267
+
268
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
269
+ // @ts-ignore
270
+ meta.errorType = null;
271
+ meta.responseType = "ResponseType";
272
+
273
+ const types = OpenapiRequestGenerator.generateTypes(meta);
274
+
275
+ // Verify only response type is generated
276
+ expect(types.TestOperationErrorType).toBeUndefined();
277
+ expect(types.TestOperationResponseType).toBe("export type TestOperationResponseType = ResponseType");
278
+ });
279
+
280
+ it("should generate only error type when response type is null", async () => {
281
+ const operation: { operationId: string; path: string; method: string } & Partial<Operation> = {
282
+ operationId: "testOperation",
283
+ path: "/test",
284
+ method: HttpMethod.GET,
285
+ responses: {
286
+ "400": { content: { "application/json": { schema: { type: "object" } } }, description: "" },
287
+ },
288
+ };
289
+
290
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
291
+ meta.errorType = "ErrorType";
292
+ // @ts-ignore
293
+ meta.responseType = null;
294
+
295
+ const types = OpenapiRequestGenerator.generateTypes(meta);
296
+
297
+ // Verify only error type is generated
298
+ expect(types.TestOperationErrorType).toBe("export type TestOperationErrorType = ErrorType");
299
+ expect(types.TestOperationResponseType).toBeUndefined();
300
+ });
301
+
302
+ it("should not generate any types when both are null", async () => {
303
+ const operation: { operationId: string; path: string; method: string } & Partial<Operation> = {
304
+ operationId: "testOperation",
305
+ path: "/test",
306
+ method: HttpMethod.GET,
307
+ };
308
+
309
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
310
+ // @ts-ignore
311
+ meta.errorType = null;
312
+ // @ts-ignore
313
+ meta.responseType = null;
314
+
315
+ const types = OpenapiRequestGenerator.generateTypes(meta);
316
+
317
+ // Verify no types are generated
318
+ expect(types.TestOperationErrorType).toBeUndefined();
319
+ expect(types.TestOperationResponseType).toBeUndefined();
320
+ });
321
+ });
322
+
323
+ describe("Generic type handling", () => {
324
+ let exportedTypes: any;
325
+
326
+ beforeEach(async () => {
327
+ exportedTypes = (await OpenapiRequestGenerator.prepareSchema(schema as unknown as Document)).exportedTypes;
328
+ });
329
+
330
+ it("should include generic type when present", async () => {
331
+ const operation: { operationId: string; path: string; method: string } & Partial<Operation> = {
332
+ operationId: "testOperation",
333
+ path: "/test",
334
+ method: HttpMethod.GET,
335
+ responses: {
336
+ "200": { content: { "application/json": { schema: { type: "object" } } }, description: "" },
337
+ },
338
+ };
339
+
340
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
341
+
342
+ const request = OpenapiRequestGenerator.generateHyperFetchRequest(meta, {
343
+ TestOperationResponseType: "string",
344
+ });
345
+ expect(request).toBe(
346
+ 'export const testOperation = client.createRequest<{response:TestOperationResponseType}>()({method: "GET", endpoint: "/test"})',
347
+ );
348
+ });
349
+
350
+ it("should generate basic request when genericType is falsy", async () => {
351
+ const operation: { operationId: string; path: string; method: string } & Partial<Operation> = {
352
+ operationId: "testOperation",
353
+ path: "/test",
354
+ method: HttpMethod.GET,
355
+ responses: {
356
+ "200": { content: { "application/json": { schema: { type: "object" } } }, description: "" },
357
+ },
358
+ };
359
+
360
+ const meta = OpenapiRequestGenerator.generateMethodMetadata(operation, exportedTypes);
361
+
362
+ const request = OpenapiRequestGenerator.generateHyperFetchRequest(meta, {});
363
+ expect(request).toBe('export const testOperation = client.createRequest()({method: "GET", endpoint: "/test"})');
364
+ });
365
+ });
366
+ });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @jest-environment node
3
+ */
4
+
5
+ import { promises as fsPromises } from "fs";
6
+ import * as path from "path";
7
+
8
+ import { Document } from "codegen/openapi";
9
+ import { getAvailableOperations } from "codegen/openapi/operations";
10
+
11
+ describe("Operations", () => {
12
+ let schema: string;
13
+ beforeAll(async () => {
14
+ const file = await fsPromises.readFile(path.resolve(__dirname, "../schemas/v3/petstore-expanded.json"), "utf8");
15
+ schema = JSON.parse(file);
16
+ });
17
+
18
+ it("should get available operations for openapi schema", async () => {
19
+ const operationIdMap = {
20
+ findPets: {
21
+ _shouldExist: ["responses", "parameters"],
22
+ path: "/pets",
23
+ method: "get",
24
+ },
25
+ addPet: {
26
+ _shouldExist: ["responses", "requestBody"],
27
+ path: "/pet",
28
+ method: "post",
29
+ },
30
+ deletePet: {
31
+ _shouldExist: ["parameters", "responses"],
32
+ path: "/pet/{petId}",
33
+ method: "delete",
34
+ },
35
+ };
36
+ getAvailableOperations(schema as unknown as Document).forEach((operation) => {
37
+ const requirements = operationIdMap[operation.operationId as keyof typeof operationIdMap];
38
+ if (requirements) {
39
+ expect(requirements.path).toEqual(operation.path);
40
+ expect(requirements.method).toEqual(operation.method);
41
+ // eslint-disable-next-line @typescript-eslint/no-loop-func
42
+ requirements._shouldExist?.forEach((req) => {
43
+ expect(operation).toHaveProperty(req);
44
+ });
45
+ }
46
+ });
47
+ });
48
+ it("should return empty object if no correct json was passed", () => {
49
+ const operations = getAvailableOperations({} as unknown as Document);
50
+ expect(operations).toStrictEqual([]);
51
+ });
52
+ });
@@ -0,0 +1,28 @@
1
+ import { promises as fsPromises } from "fs";
2
+ import path from "path";
3
+
4
+ import { getBaseUrl, isUrl, normalizeOperationId } from "codegen/openapi/utils";
5
+ import { Document } from "codegen/openapi";
6
+
7
+ describe("Utils", () => {
8
+ it("should check if provided path is url or not", () => {
9
+ const urlPath = "https://petstore3.swagger.io/api/v3/openapi.json";
10
+ const localpath = "./petstore.json";
11
+ expect(isUrl(urlPath)).toBe(true);
12
+ expect(isUrl(localpath)).toBe(false);
13
+ });
14
+
15
+ it("should normalize operation id", () => {
16
+ const normalizedOperationId = normalizeOperationId("/pets by id");
17
+ expect(normalizedOperationId).toBe("Pets_by_id");
18
+ });
19
+
20
+ it("should return available server link or empty string", async () => {
21
+ const file = await fsPromises.readFile(path.resolve(__dirname, "../schemas/v3/petstore-expanded.json"), "utf8");
22
+ const schema = JSON.parse(file);
23
+ const baseUrl = getBaseUrl(schema);
24
+ const emptyString = getBaseUrl({} as unknown as Document);
25
+ expect(baseUrl).toEqual("/api/v3");
26
+ expect(emptyString).toEqual("");
27
+ });
28
+ });
@@ -0,0 +1,106 @@
1
+ import { jest } from "@jest/globals";
2
+ import { input, select, confirm } from "@inquirer/prompts";
3
+
4
+ import { generate } from "commands/generate";
5
+ import { handleError } from "utils/handle-error";
6
+ import { preFlightGenerate } from "preflights/preflight-generate";
7
+ import { OpenapiRequestGenerator } from "codegen/openapi/generator";
8
+
9
+ // Mocks
10
+ jest.mock("utils/handle-error", () => ({ handleError: jest.fn() }));
11
+ jest.mock("preflights/preflight-generate", () => {
12
+ const fakeConfig = {
13
+ tsx: true,
14
+ aliases: { api: "/tmp", hooks: "/tmp", ui: "/tmp", components: "/tmp", lib: "/tmp" },
15
+ resolvedPaths: { cwd: "/tmp", api: "/tmp", hooks: "/tmp", ui: "/tmp", components: "/tmp", lib: "/tmp" },
16
+ };
17
+ return {
18
+ preFlightGenerate: jest.fn(async () => ({ errors: {}, config: fakeConfig })),
19
+ };
20
+ });
21
+ jest.mock("codegen/openapi/generator", () => {
22
+ class FakeGenerator {
23
+ static getSchemaFromUrl = jest.fn(async () => ({ openapi: "3.0.0", paths: {} }));
24
+ generateFile = jest.fn(async () => undefined);
25
+ }
26
+ return { OpenapiRequestGenerator: FakeGenerator };
27
+ });
28
+ jest.mock("utils/spinner", () => ({
29
+ spinner: jest.fn(() => ({
30
+ start: jest.fn(() => ({ succeed: jest.fn(), fail: jest.fn() })),
31
+ })),
32
+ }));
33
+ jest.mock("utils/logger", () => ({ logger: { info: jest.fn(), error: jest.fn(), log: jest.fn() } }));
34
+ jest.mock("@inquirer/prompts", () => ({
35
+ input: jest.fn(),
36
+ select: jest.fn(),
37
+ confirm: jest.fn(),
38
+ }));
39
+
40
+ describe("cli generate command", () => {
41
+ const originalArgv = process.argv;
42
+ const exitSpy = jest
43
+ .spyOn(process, "exit")
44
+ .mockImplementation((() => undefined) as (code?: string | number | null | undefined) => never);
45
+
46
+ beforeEach(() => {
47
+ jest.clearAllMocks();
48
+ });
49
+
50
+ afterAll(() => {
51
+ exitSpy.mockRestore();
52
+ process.argv = originalArgv;
53
+ });
54
+
55
+ it("bypasses prompts and generates when params are provided", async () => {
56
+ process.argv = [
57
+ "/usr/local/bin/node",
58
+ "cli",
59
+ "--template",
60
+ "openapi",
61
+ "--url",
62
+ "https://example.com/openapi.json",
63
+ "--fileName",
64
+ "api-openapi.sdk.ts",
65
+ "--cwd",
66
+ "/tmp",
67
+ "--overwrite",
68
+ ];
69
+
70
+ await generate.parseAsync(process.argv, { from: "user" });
71
+
72
+ expect(preFlightGenerate).toHaveBeenCalled();
73
+ expect(select).not.toHaveBeenCalled();
74
+ expect(input).not.toHaveBeenCalled();
75
+ expect(confirm).not.toHaveBeenCalled();
76
+ expect(OpenapiRequestGenerator.getSchemaFromUrl).toHaveBeenCalledWith({
77
+ url: "https://example.com/openapi.json",
78
+ config: expect.any(Object),
79
+ });
80
+ expect(process.exit).toHaveBeenCalledWith(0);
81
+ });
82
+
83
+ it("handles invalid params by displaying error", async () => {
84
+ process.argv = [
85
+ "/usr/local/bin/node",
86
+ "cli",
87
+ "--template",
88
+ "invalid-template",
89
+ "--url",
90
+ "not-a-url",
91
+ "--fileName",
92
+ "api-invalid.sdk.ts",
93
+ "--cwd",
94
+ "/tmp",
95
+ ];
96
+
97
+ await generate.parseAsync(process.argv, { from: "user" });
98
+
99
+ expect(select).not.toHaveBeenCalled();
100
+ expect(input).not.toHaveBeenCalled();
101
+ expect(confirm).not.toHaveBeenCalled();
102
+ expect(handleError).toHaveBeenCalled();
103
+ expect(handleError).toHaveBeenCalledWith(expect.any(Error));
104
+ expect(process.exit).not.toHaveBeenCalledWith(0);
105
+ });
106
+ });
File without changes
@@ -0,0 +1 @@
1
+ import "jest-extended";
@@ -0,0 +1,5 @@
1
+ import { AbortController } from "abortcontroller-polyfill/dist/cjs-ponyfill";
2
+
3
+ if (!global.AbortController) {
4
+ global.AbortController = AbortController as any;
5
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "noEmit": true,
5
+ "baseUrl": "../src",
6
+ "moduleResolution": "node",
7
+ "esModuleInterop": true,
8
+ "allowSyntheticDefaultImports": true
9
+ },
10
+ "exclude": ["node_modules", "dist", "__temp__"]
11
+ }
package/jest.config.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { Config } from "@jest/types";
2
+
3
+ import { getJestConfig } from "../../jest.config";
4
+
5
+ const config: Config.InitialOptions = getJestConfig();
6
+ export default config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyper-fetch/cli",
3
- "version": "7.5.2",
3
+ "version": "7.5.3",
4
4
  "description": "Hyper Fetch cli for code generation and utilities",
5
5
  "author": "Maciej Pyrc <maciekpyrc@gmail.com>, Kacper Skawina <kacper.skawina@gmail.com>",
6
6
  "homepage": "https://hyperfetch.bettertyped.com/",
package/project.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "cli",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json"
4
+ }