@jaypie/testkit 1.0.29 → 1.1.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.
Files changed (41) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +2 -325
  3. package/dist/__tests__/constants.spec.d.ts +1 -0
  4. package/dist/__tests__/expressHandler-supertest.mock.spec.d.ts +1 -0
  5. package/dist/__tests__/index.spec.d.ts +1 -0
  6. package/dist/__tests__/jaypie.mock.spec.d.ts +1 -0
  7. package/dist/__tests__/jsonApiSchema.module.spec.d.ts +1 -0
  8. package/dist/__tests__/matchers.module.spec.d.ts +1 -0
  9. package/dist/__tests__/mockLog.module.spec.d.ts +1 -0
  10. package/dist/__tests__/sqsTestRecords.function.spec.d.ts +1 -0
  11. package/dist/__tests__/toThrowError.matcher.spec.d.ts +1 -0
  12. package/dist/__tests__/toThrowJaypieError.matcher.spec.d.ts +1 -0
  13. package/dist/constants.d.ts +19 -0
  14. package/{src/index.js → dist/index.d.ts} +4 -15
  15. package/dist/index.js +467 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/jaypie.mock.d.ts +104 -0
  18. package/dist/jsonApiSchema.module.d.ts +61 -0
  19. package/dist/matchers/toBeCalledAboveTrace.matcher.d.ts +3 -0
  20. package/dist/matchers/toBeCalledWithInitialParams.matcher.d.ts +4 -0
  21. package/dist/matchers/toBeClass.matcher.d.ts +3 -0
  22. package/dist/matchers/toBeJaypieError.matcher.d.ts +3 -0
  23. package/dist/matchers/toMatch.matcher.d.ts +12 -0
  24. package/dist/matchers/toThrowError.matcher.d.ts +4 -0
  25. package/dist/matchers/toThrowJaypieError.matcher.d.ts +16 -0
  26. package/dist/matchers.module.d.ts +25 -0
  27. package/dist/mockLog.module.d.ts +5 -0
  28. package/dist/sqsTestRecords.function.d.ts +14 -0
  29. package/package.json +35 -42
  30. package/src/constants.js +0 -28
  31. package/src/jaypie.mock.js +0 -371
  32. package/src/jsonApiSchema.module.js +0 -39
  33. package/src/matchers/toBeCalledAboveTrace.matcher.js +0 -47
  34. package/src/matchers/toBeCalledWithInitialParams.matcher.js +0 -44
  35. package/src/matchers/toBeClass.matcher.js +0 -44
  36. package/src/matchers/toBeJaypieError.matcher.js +0 -52
  37. package/src/matchers/toMatch.matcher.js +0 -76
  38. package/src/matchers/toThrowJaypieError.matcher.js +0 -111
  39. package/src/matchers.module.js +0 -58
  40. package/src/mockLog.module.js +0 -99
  41. package/src/sqsTestRecords.function.js +0 -53
@@ -0,0 +1,61 @@
1
+ import { JsonApiData, JsonApiError } from "./types/jaypie-testkit";
2
+ export declare const jsonApiErrorSchema: {
3
+ readonly type: "object";
4
+ readonly properties: {
5
+ readonly errors: {
6
+ readonly type: "array";
7
+ readonly items: {
8
+ readonly type: "object";
9
+ readonly properties: {
10
+ readonly status: {
11
+ readonly type: "number";
12
+ };
13
+ readonly title: {
14
+ readonly type: "string";
15
+ };
16
+ readonly detail: {
17
+ readonly type: "string";
18
+ };
19
+ };
20
+ readonly required: readonly ["status", "title"];
21
+ };
22
+ readonly minItems: 1;
23
+ };
24
+ };
25
+ readonly required: readonly ["errors"];
26
+ };
27
+ export declare const jsonApiSchema: {
28
+ readonly type: "object";
29
+ readonly properties: {
30
+ readonly data: {
31
+ readonly type: "object";
32
+ readonly properties: {
33
+ readonly id: {
34
+ readonly type: "string";
35
+ };
36
+ readonly type: {
37
+ readonly type: "string";
38
+ };
39
+ readonly attributes: {
40
+ readonly type: "object";
41
+ };
42
+ readonly links: {
43
+ readonly type: "object";
44
+ };
45
+ readonly meta: {
46
+ readonly type: "object";
47
+ };
48
+ readonly relationships: {
49
+ readonly type: "object";
50
+ };
51
+ };
52
+ readonly required: readonly ["id", "type"];
53
+ };
54
+ readonly meta: {
55
+ readonly type: "object";
56
+ };
57
+ };
58
+ readonly required: readonly ["data"];
59
+ };
60
+ export declare const isJsonApiError: (obj: unknown) => obj is JsonApiError;
61
+ export declare const isJsonApiData: (obj: unknown) => obj is JsonApiData;
@@ -0,0 +1,3 @@
1
+ import { LogMock, MatcherResult } from "../types/jaypie-testkit";
2
+ declare const calledAboveTrace: (log: LogMock) => MatcherResult;
3
+ export default calledAboveTrace;
@@ -0,0 +1,4 @@
1
+ import { Mock } from "vitest";
2
+ import { MatcherResult } from "../types/jaypie-testkit";
3
+ declare const toBeCalledWithInitialParams: (received: Mock, ...passed: unknown[]) => MatcherResult;
4
+ export default toBeCalledWithInitialParams;
@@ -0,0 +1,3 @@
1
+ import { MatcherResult } from "../types/jaypie-testkit";
2
+ declare const toBeClass: (received: unknown) => MatcherResult;
3
+ export default toBeClass;
@@ -0,0 +1,3 @@
1
+ import { MatcherResult } from "../types/jaypie-testkit";
2
+ declare const toBeJaypieError: (received: unknown) => MatcherResult;
3
+ export default toBeJaypieError;
@@ -0,0 +1,12 @@
1
+ import { MatcherResult } from "../types/jaypie-testkit";
2
+ export declare const toMatchBase64: (subject: string) => MatcherResult;
3
+ export declare const toMatchJwt: (subject: string) => MatcherResult;
4
+ export declare const toMatchMongoId: (subject: string) => MatcherResult;
5
+ export declare const toMatchSignedCookie: (subject: string) => MatcherResult;
6
+ export declare const toMatchUuid4: (subject: string) => MatcherResult;
7
+ export declare const toMatchUuid5: (subject: string) => MatcherResult;
8
+ /**
9
+ * Determines if subject matches a UUID pattern.
10
+ * Does _NOT_ check if the UUID is valid.
11
+ */
12
+ export declare const toMatchUuid: (subject: string) => MatcherResult;
@@ -0,0 +1,4 @@
1
+ import { MatcherResult } from "../types/jaypie-testkit";
2
+ type ReceivedFunction = () => unknown | Promise<unknown>;
3
+ declare const toThrowError: (received: ReceivedFunction) => Promise<MatcherResult>;
4
+ export default toThrowError;
@@ -0,0 +1,16 @@
1
+ import { ProjectError } from "@jaypie/core";
2
+ import { MatcherResult } from "../types/jaypie-testkit";
3
+ type ReceivedFunction = () => unknown | Promise<unknown>;
4
+ type ErrorConstructor = new () => ProjectError;
5
+ declare const toThrowJaypieError: (received: ReceivedFunction, expected?: ProjectError | (() => ProjectError) | ErrorConstructor) => Promise<MatcherResult>;
6
+ declare const toThrowBadGatewayError: (received: ReceivedFunction) => Promise<MatcherResult>;
7
+ declare const toThrowBadRequestError: (received: ReceivedFunction) => Promise<MatcherResult>;
8
+ declare const toThrowConfigurationError: (received: ReceivedFunction) => Promise<MatcherResult>;
9
+ declare const toThrowForbiddenError: (received: ReceivedFunction) => Promise<MatcherResult>;
10
+ declare const toThrowGatewayTimeoutError: (received: ReceivedFunction) => Promise<MatcherResult>;
11
+ declare const toThrowInternalError: (received: ReceivedFunction) => Promise<MatcherResult>;
12
+ declare const toThrowNotFoundError: (received: ReceivedFunction) => Promise<MatcherResult>;
13
+ declare const toThrowUnauthorizedError: (received: ReceivedFunction) => Promise<MatcherResult>;
14
+ declare const toThrowUnavailableError: (received: ReceivedFunction) => Promise<MatcherResult>;
15
+ export default toThrowJaypieError;
16
+ export { toThrowBadGatewayError, toThrowBadRequestError, toThrowConfigurationError, toThrowForbiddenError, toThrowGatewayTimeoutError, toThrowInternalError, toThrowNotFoundError, toThrowUnauthorizedError, toThrowUnavailableError, };
@@ -0,0 +1,25 @@
1
+ declare const matchers: {
2
+ toBeCalledAboveTrace: (log: import("./types/jaypie-testkit.js").LogMock) => import("./types/jaypie-testkit.js").MatcherResult;
3
+ toBeCalledWithInitialParams: (received: import("vitest").Mock, ...passed: unknown[]) => import("./types/jaypie-testkit.js").MatcherResult;
4
+ toBeClass: (received: unknown) => import("./types/jaypie-testkit.js").MatcherResult;
5
+ toBeJaypieError: (received: unknown) => import("./types/jaypie-testkit.js").MatcherResult;
6
+ toMatchBase64: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
7
+ toMatchJwt: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
8
+ toMatchMongoId: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
9
+ toMatchSignedCookie: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
10
+ toMatchUuid: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
11
+ toMatchUuid4: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
12
+ toMatchUuid5: (subject: string) => import("./types/jaypie-testkit.js").MatcherResult;
13
+ toThrowBadGatewayError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
14
+ toThrowBadRequestError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
15
+ toThrowConfigurationError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
16
+ toThrowError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
17
+ toThrowForbiddenError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
18
+ toThrowGatewayTimeoutError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
19
+ toThrowInternalError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
20
+ toThrowJaypieError: (received: () => unknown | Promise<unknown>, expected?: import("@jaypie/core").ProjectError | (() => import("@jaypie/core").ProjectError) | (new () => import("@jaypie/core").ProjectError)) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
21
+ toThrowNotFoundError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
22
+ toThrowUnauthorizedError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
23
+ toThrowUnavailableError: (received: () => unknown | Promise<unknown>) => Promise<import("./types/jaypie-testkit.js").MatcherResult>;
24
+ };
25
+ export default matchers;
@@ -0,0 +1,5 @@
1
+ import { Log } from "@jaypie/core";
2
+ import { LogMock } from "./types/jaypie-testkit";
3
+ export declare function mockLogFactory(): LogMock;
4
+ export declare function spyLog(log: Log): void;
5
+ export declare function restoreLog(log: Log): void;
@@ -0,0 +1,14 @@
1
+ interface SQSEvent {
2
+ Records: Array<{
3
+ body: string;
4
+ messageId?: string | number;
5
+ [key: string]: unknown;
6
+ }>;
7
+ }
8
+ /**
9
+ * Creates a mock SQS event with the given records
10
+ * @param records - Array of records or individual records to include in the event
11
+ * @returns SQS event object with Records array
12
+ */
13
+ declare const sqsTestRecords: (...records: Array<unknown>) => SQSEvent;
14
+ export default sqsTestRecords;
package/package.json CHANGED
@@ -1,59 +1,52 @@
1
1
  {
2
2
  "name": "@jaypie/testkit",
3
- "version": "1.0.29",
3
+ "version": "1.1.1",
4
+ "license": "MIT",
4
5
  "author": "Finlayson Studio",
5
6
  "type": "module",
6
7
  "exports": {
7
- ".": "./src/index.js",
8
- "./mock": "./src/jaypie.mock.js"
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./mock": {
13
+ "types": "./dist/jaypie.mock.d.ts",
14
+ "import": "./dist/jaypie.mock.js"
15
+ }
9
16
  },
10
- "main": "src/index.js",
17
+ "main": "./dist/index.js",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist"
22
+ ],
11
23
  "scripts": {
12
- "format": "npm run format:package && npm run format:lint",
13
- "format:lint": "eslint --fix .",
14
- "format:package": "sort-package-json ./package.json",
15
- "init:commander": "hygen jaypie commander-init",
16
- "init:deploy": "hygen jaypie workflow-npm",
24
+ "build": "rollup --config",
25
+ "format": "eslint --fix .",
17
26
  "lint": "eslint .",
18
- "new": "hygen jaypie vite",
19
- "new:command": "hygen jaypie command",
20
- "new:constants": "hygen jaypie constants",
21
- "new:hygen": "hygen jaypie hygen",
22
- "new:index": "hygen jaypie index",
23
- "new:model": "hygen jaypie model",
24
- "new:test": "hygen jaypie vitest",
25
- "test": "vitest",
26
- "test:spec:constants": "vitest run ./src/__tests__/constants.spec.js",
27
- "test:spec:expressHandler.mock": "vitest run ./src/__tests__/expressHandler-supertest.mock.spec.js",
28
- "test:spec:index": "vitest run ./src/__tests__/index.spec.js",
29
- "test:spec:jaypie.mock": "vitest run ./src/__tests__/jaypie.mock.spec.js",
30
- "test:spec:jsonApiSchema.module": "vitest run ./src/__tests__/jsonApiSchema.module.spec.js",
31
- "test:spec:matchers.module": "vitest run ./src/__tests__/matchers.module.spec.js",
32
- "test:spec:mockLog.module": "vitest run ./src/__tests__/mockLog.module.spec.js",
33
- "test:spec:sqsTestRecords.function": "vitest run ./src/__tests__/sqsTestRecords.function.spec.js",
34
- "test:spec:toBeCalledAboveTrace.matcher": "vitest run ./src/matchers/__tests__/toBeCalledAboveTrace.matcher.spec.js",
35
- "test:spec:toBeCalledWithInitialParams.matcher": "vitest run ./src/matchers/__tests__/toBeCalledWithInitialParams.matcher.spec.js",
36
- "test:spec:toBeClass.matcher": "vitest run ./src/matchers/__tests__/toBeClass.matcher.spec.js",
37
- "test:spec:toBeJaypieError.matcher": "vitest run ./src/matchers/__tests__/toBeJaypieError.matcher.spec.js",
38
- "test:spec:toMatch.matcher": "vitest run ./src/matchers/__tests__/toMatch.matcher.spec.js",
39
- "test:spec:toThrowJaypieError.matcher": "vitest run ./src/matchers/__tests__/toThrowJaypieError.matcher.spec.js"
27
+ "test": "vitest run .",
28
+ "test:watch": "vitest watch ."
40
29
  },
41
30
  "dependencies": {
42
- "@jaypie/core": "^1.0.33",
31
+ "@jaypie/core": "^1.1.0",
32
+ "@jaypie/eslint": "^1.1.6",
43
33
  "jaypie": "^1.0.44",
44
34
  "jest-json-schema": "^6.1.0",
45
35
  "lodash.isequal": "^4.5.0",
46
36
  "uuid": "^9.0.1"
47
37
  },
48
38
  "devDependencies": {
49
- "eslint": "^8.57.0",
50
- "eslint-config-jaypie": "^1.0.7",
51
- "express": "^4.19.2",
52
- "hygen": "^6.2.11",
53
- "jest-extended": "^4.0.2",
54
- "prettier": "^3.2.5",
55
- "sort-package-json": "^2.8.0",
56
- "supertest": "^7.0.0",
57
- "vitest": "^1.4.0"
58
- }
39
+ "@types/express": "^5.0.0",
40
+ "@types/lodash.isequal": "^4.5.8",
41
+ "@types/node": "^20.0.0",
42
+ "@types/supertest": "^6.0.2",
43
+ "express": "^4.21.1",
44
+ "rollup": "^4.29.1",
45
+ "typescript": "^5.0.0",
46
+ "vitest": "^2.1.8"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "gitHead": "8b953596e065e06c57e75082dc5d3a2267b6b8bd"
59
52
  }
package/src/constants.js DELETED
@@ -1,28 +0,0 @@
1
- //
2
- //
3
- // Constants
4
- //
5
-
6
- export const LOG = {
7
- LEVEL: {
8
- ALL: "all",
9
- DEBUG: "debug",
10
- ERROR: "error",
11
- FATAL: "fatal",
12
- INFO: "info",
13
- SILENT: "silent",
14
- TRACE: "trace",
15
- WARN: "warn",
16
- },
17
- };
18
-
19
- export const RE_BASE64_PATTERN = /^[a-zA-Z0-9\\+\\/]+$/;
20
- export const RE_JWT_PATTERN = /^([^.]+)\.([^.]+)\.([^.]+)$/;
21
- export const RE_MONGO_ID_PATTERN = /^[a-f0-9]{24}$/i;
22
- export const RE_SIGNED_COOKIE_PATTERN = /^s:([^.]+)\.([^.]+)$/;
23
- export const RE_UUID_4_PATTERN =
24
- /^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$/i;
25
- export const RE_UUID_5_PATTERN =
26
- /^[a-f0-9]{8}-?[a-f0-9]{4}-?5[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$/i;
27
- export const RE_UUID_PATTERN =
28
- /^[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$/i;
@@ -1,371 +0,0 @@
1
- import { getMessages as originalGetMessages } from "@jaypie/aws";
2
- import { force, uuid as originalUuid } from "@jaypie/core";
3
- import {
4
- // Core utilities
5
- HTTP,
6
- JAYPIE,
7
- log,
8
- // Errors
9
- BadGatewayError as BadGatewayErrorOriginal,
10
- BadRequestError as BadRequestErrorOriginal,
11
- ConfigurationError as ConfigurationErrorOriginal,
12
- ForbiddenError as ForbiddenErrorOriginal,
13
- GatewayTimeoutError as GatewayTimeoutErrorOriginal,
14
- GoneError as GoneErrorOriginal,
15
- IllogicalError as IllogicalErrorOriginal,
16
- InternalError as InternalErrorOriginal,
17
- MethodNotAllowedError as MethodNotAllowedErrorOriginal,
18
- MultiError as MultiErrorOriginal,
19
- NotFoundError as NotFoundErrorOriginal,
20
- NotImplementedError as NotImplementedErrorOriginal,
21
- ProjectError as ProjectErrorOriginal,
22
- ProjectMultiError as ProjectMultiErrorOriginal,
23
- RejectedError as RejectedErrorOriginal,
24
- TeapotError as TeapotErrorOriginal,
25
- UnauthorizedError as UnauthorizedErrorOriginal,
26
- UnavailableError as UnavailableErrorOriginal,
27
- UnhandledError as UnhandledErrorOriginal,
28
- UnreachableCodeError as UnreachableCodeErrorOriginal,
29
- } from "@jaypie/core";
30
- import { beforeAll, vi } from "vitest";
31
-
32
- import { spyLog } from "./mockLog.module.js";
33
-
34
- //
35
- //
36
- // Setup
37
- //
38
-
39
- const TAG = JAYPIE.LIB.TESTKIT;
40
-
41
- // Export all the modules from Jaypie packages:
42
-
43
- export * from "@jaypie/aws";
44
- export * from "@jaypie/core";
45
- export * from "@jaypie/express";
46
- export * from "@jaypie/datadog";
47
- export * from "@jaypie/lambda";
48
- export * from "@jaypie/mongoose";
49
-
50
- // Spy on log:
51
-
52
- beforeAll(() => {
53
- spyLog(log);
54
- });
55
-
56
- // afterEach(() => {
57
- // This is not necessary because the log isn't being used outside tests:
58
- // restoreLog(log);
59
- // The is the client's responsibility:
60
- // vi.clearAllMocks();
61
- // });
62
-
63
- //
64
- //
65
- // Mock Functions
66
- //
67
-
68
- // @jaypie/aws
69
-
70
- export const getMessages = vi.fn((...params) => originalGetMessages(...params));
71
-
72
- export const getSecret = vi.fn(() => {
73
- return `_MOCK_SECRET_[${TAG}]`;
74
- });
75
-
76
- export const sendBatchMessages = vi.fn(() => {
77
- // TODO: better default value
78
- return { value: `_MOCK_BATCH_MESSAGES_[${TAG}]` };
79
- });
80
-
81
- export const sendMessage = vi.fn(() => {
82
- // TODO: better default value
83
- return { value: `_MOCK_MESSAGE_[${TAG}]` };
84
- });
85
-
86
- // @jaypie/core Errors
87
-
88
- export const BadGatewayError = vi.fn((...params) => {
89
- return BadGatewayErrorOriginal(...params);
90
- });
91
- export const BadRequestError = vi.fn((...params) => {
92
- return BadRequestErrorOriginal(...params);
93
- });
94
- export const ConfigurationError = vi.fn((...params) => {
95
- return ConfigurationErrorOriginal(...params);
96
- });
97
- export const ForbiddenError = vi.fn((...params) => {
98
- return ForbiddenErrorOriginal(...params);
99
- });
100
- export const GatewayTimeoutError = vi.fn((...params) => {
101
- return GatewayTimeoutErrorOriginal(...params);
102
- });
103
- export const GoneError = vi.fn((...params) => {
104
- return GoneErrorOriginal(...params);
105
- });
106
- export const IllogicalError = vi.fn((...params) => {
107
- return IllogicalErrorOriginal(...params);
108
- });
109
- export const InternalError = vi.fn((...params) => {
110
- return InternalErrorOriginal(...params);
111
- });
112
- export const MethodNotAllowedError = vi.fn((...params) => {
113
- return MethodNotAllowedErrorOriginal(...params);
114
- });
115
- export const MultiError = vi.fn((...params) => {
116
- return MultiErrorOriginal(...params);
117
- });
118
- export const NotFoundError = vi.fn((...params) => {
119
- return NotFoundErrorOriginal(...params);
120
- });
121
- export const NotImplementedError = vi.fn((...params) => {
122
- return NotImplementedErrorOriginal(...params);
123
- });
124
- export const ProjectError = vi.fn((...params) => {
125
- return ProjectErrorOriginal(...params);
126
- });
127
- export const ProjectMultiError = vi.fn((...params) => {
128
- return ProjectMultiErrorOriginal(...params);
129
- });
130
- export const RejectedError = vi.fn((...params) => {
131
- return RejectedErrorOriginal(...params);
132
- });
133
- export const TeapotError = vi.fn((...params) => {
134
- return TeapotErrorOriginal(...params);
135
- });
136
- export const UnauthorizedError = vi.fn((...params) => {
137
- return UnauthorizedErrorOriginal(...params);
138
- });
139
- export const UnavailableError = vi.fn((...params) => {
140
- return UnavailableErrorOriginal(...params);
141
- });
142
- export const UnhandledError = vi.fn((...params) => {
143
- return UnhandledErrorOriginal(...params);
144
- });
145
- export const UnreachableCodeError = vi.fn((...params) => {
146
- return UnreachableCodeErrorOriginal(...params);
147
- });
148
-
149
- // @jaypie/core Functions
150
-
151
- export const envBoolean = vi.fn(() => {
152
- return true;
153
- });
154
-
155
- export const jaypieHandler = vi.fn(
156
- (
157
- handler,
158
- {
159
- setup = [],
160
- teardown = [],
161
- unavailable = force.boolean(process.env.PROJECT_UNAVAILABLE),
162
- validate = [],
163
- } = {},
164
- ) => {
165
- return async (...args) => {
166
- let result;
167
- let thrownError;
168
- if (unavailable) throw new UnavailableError();
169
- for (const validator of validate) {
170
- if (typeof validator === "function") {
171
- const valid = await validator(...args);
172
- if (valid === false) {
173
- throw new BadRequestError();
174
- }
175
- }
176
- }
177
- try {
178
- for (const setupFunction of setup) {
179
- if (typeof setupFunction === "function") {
180
- await setupFunction(...args);
181
- }
182
- }
183
- result = handler(...args);
184
- } catch (error) {
185
- thrownError = error;
186
- }
187
- for (const teardownFunction of teardown) {
188
- if (typeof teardownFunction === "function") {
189
- try {
190
- await teardownFunction(...args);
191
- } catch (error) {
192
- // eslint-disable-next-line no-console
193
- console.error(error);
194
- }
195
- }
196
- }
197
- if (thrownError) {
198
- throw thrownError;
199
- }
200
- return result;
201
- };
202
- },
203
- );
204
-
205
- export const sleep = vi.fn(() => {
206
- return true;
207
- });
208
-
209
- export const uuid = vi.fn(originalUuid);
210
-
211
- // @jaypie/datadog
212
-
213
- export const submitMetric = vi.fn(() => {
214
- return true;
215
- });
216
-
217
- export const submitMetricSet = vi.fn(() => {
218
- return true;
219
- });
220
-
221
- // @jaypie/express
222
-
223
- export const expressHandler = vi.fn((handler, props = {}) => {
224
- // If handler is an object and options is a function, swap them
225
- if (typeof handler === "object" && typeof props === "function") {
226
- const temp = handler;
227
- handler = props;
228
- props = temp;
229
- }
230
- if (typeof handler !== "function") {
231
- throw new BadRequestError("handler must be a function");
232
- }
233
- if (!props) {
234
- props = {};
235
- }
236
- props.setup = force.array(props.setup); // allows a single item
237
- props.teardown = force.array(props.teardown); // allows a single item
238
- if (!Array.isArray(props.setup)) {
239
- props.setup = [];
240
- }
241
- if (props.locals === null) {
242
- throw new BadRequestError("locals cannot be null");
243
- }
244
- if (props.locals) {
245
- if (typeof props.locals !== "object" || Array.isArray(props.locals)) {
246
- throw new BadRequestError("locals must be an object");
247
- }
248
- // Locals
249
- const keys = Object.keys(props.locals);
250
- if (keys.length > 0) {
251
- props.setup.push((req = {}) => {
252
- if (typeof req !== "object") {
253
- throw new BadRequestError("req must be an object");
254
- }
255
- // Set req.locals if it doesn't exist
256
- if (!req.locals) req.locals = {};
257
- if (typeof req.locals !== "object" || Array.isArray(req.locals)) {
258
- throw new BadRequestError("req.locals must be an object");
259
- }
260
- if (!req.locals._jaypie) req.locals._jaypie = {};
261
- });
262
- const localsSetup = async (localsReq, localsRes) => {
263
- for (let i = 0; i < keys.length; i += 1) {
264
- const key = keys[i];
265
- if (typeof props.locals[key] === "function") {
266
- // eslint-disable-next-line no-await-in-loop
267
- localsReq.locals[key] = await props.locals[key](
268
- localsReq,
269
- localsRes,
270
- );
271
- } else {
272
- localsReq.locals[key] = props.locals[key];
273
- }
274
- }
275
- };
276
- props.setup.push(localsSetup);
277
- }
278
- }
279
- const jaypieFunction = jaypieHandler(handler, props);
280
- return async (req = {}, res = {}, ...extra) => {
281
- const status = HTTP.CODE.OK;
282
- let response;
283
- let supertestMode = false;
284
- if (
285
- res &&
286
- typeof res.socket === "object" &&
287
- res.constructor.name === "ServerResponse"
288
- ) {
289
- // Use the response object in supertest mode
290
- supertestMode = true;
291
- }
292
- try {
293
- response = await jaypieFunction(req, res, ...extra);
294
- } catch (error) {
295
- // In the mock context, if status is a function we are in a "supertest"
296
- if (supertestMode) {
297
- // In theory jaypieFunction has handled all errors
298
- const errorStatus = error.status || HTTP.CODE.INTERNAL_SERVER_ERROR;
299
- let errorResponse;
300
- if (typeof error.json === "function") {
301
- errorResponse = error.json();
302
- } else {
303
- // This should never happen
304
- errorResponse = new UnhandledError().json();
305
- }
306
- res.status(errorStatus).json(errorResponse);
307
- return;
308
- } else {
309
- // else, res.status is not a function, throw the error
310
- throw error;
311
- }
312
- }
313
- if (supertestMode) {
314
- if (response) {
315
- // res.status(200);
316
- if (typeof response === "object") {
317
- if (typeof response.json === "function") {
318
- res.json(response.json());
319
- } else {
320
- res.status(status).json(response);
321
- }
322
- } else if (typeof response === "string") {
323
- try {
324
- res.status(status).json(JSON.parse(response));
325
- } catch (error) {
326
- if (supertestMode) {
327
- res.status(status).send(response);
328
- }
329
- }
330
- } else if (response === true) {
331
- res.status(HTTP.CODE.CREATED).send();
332
- } else {
333
- res.status(status).send(response);
334
- }
335
- } else {
336
- res.status(HTTP.CODE.NO_CONTENT).send();
337
- }
338
- } else {
339
- return response;
340
- }
341
- };
342
- });
343
-
344
- // @jaypie/lambda
345
-
346
- // For testing, this is the same as the jaypieHandler
347
- export const lambdaHandler = vi.fn((handler, props = {}) => {
348
- // If handler is an object and options is a function, swap them
349
- if (typeof handler === "object" && typeof props === "function") {
350
- const temp = handler;
351
- handler = props;
352
- props = temp;
353
- }
354
- return async (event, context, ...extra) => {
355
- return jaypieHandler(handler, props)(event, context, ...extra);
356
- };
357
- });
358
-
359
- // @jaypie/mongoose
360
-
361
- export const connect = vi.fn(() => {
362
- return true;
363
- });
364
-
365
- export const connectFromSecretEnv = vi.fn(() => {
366
- return true;
367
- });
368
-
369
- export const disconnect = vi.fn(() => {
370
- return true;
371
- });