sm-utility 1.4.4 → 2.1.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/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ // Packages below are not fully implemented yet
14
+ // export * from './array';
15
+ // export * from './string';
16
+ __exportStar(require("./date"), exports);
17
+ __exportStar(require("./general"), exports);
18
+ __exportStar(require("./infrastructure"), exports);
19
+ __exportStar(require("./logger"), exports);
20
+ __exportStar(require("./request"), exports);
21
+ __exportStar(require("./stubs"), exports);
package/package.json CHANGED
@@ -1,31 +1,28 @@
1
1
  {
2
2
  "name": "sm-utility",
3
- "version": "1.4.4",
3
+ "version": "2.1.0",
4
4
  "description": "reusable utility codes for sm projects",
5
5
  "main": "index.js",
6
- "types": "index.d.ts",
6
+ "types": "./index.d.ts",
7
+ "typings": "./index.d.ts",
7
8
  "scripts": {
8
- "clean": "rm -rf general/ date/ string/ array/ logger/ request/ infrastructure/",
9
- "build": "npm run clean && tsc",
10
- "prepare": "npm run build",
11
- "test": "echo \"Error: no test specified\" && exit 1"
9
+ "clean": "rm -rf dist",
10
+ "prebuild":"npm run clean",
11
+ "build": "tsc",
12
+ "postbuild": "npm run copy-files",
13
+ "copy-files": "copyfiles package.json README.md ./dist",
14
+ "publish-package": "npm run build && cd ./dist && npm publish"
12
15
  },
13
16
  "author": "Caio Poyares",
14
17
  "license": "ISC",
15
18
  "files": [
16
- "/infrastructure",
17
- "/general",
18
- "/date",
19
- "/string",
20
- "/array",
21
- "/logger",
22
- "/request",
23
- "/typings"
19
+ "*/**"
24
20
  ],
25
21
  "devDependencies": {
26
22
  "@types/express": "^4.17.11",
27
23
  "@types/node": "^14.14.40",
28
24
  "@types/uuid": "^8.3.1",
25
+ "copyfiles": "^2.4.1",
29
26
  "typescript": "^4.2.4"
30
27
  },
31
28
  "dependencies": {
@@ -1,3 +1,9 @@
1
- import { AxiosInstance } from 'axios';
2
- import { RequestConfig } from './types';
3
- export declare function createApi(axiosConfig?: RequestConfig): AxiosInstance;
1
+ import { AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ declare module 'axios' {
3
+ interface AxiosRequestConfig {
4
+ meta?: Record<string, any>;
5
+ logRequest?: boolean;
6
+ logResponse?: boolean;
7
+ }
8
+ }
9
+ export declare function createApi(axiosConfig?: Omit<AxiosRequestConfig, "meta">): AxiosInstance;
package/request/index.js CHANGED
@@ -10,7 +10,7 @@ const logger_1 = require("../logger");
10
10
  function createApi(axiosConfig) {
11
11
  const axiosApi = axios_1.default.create(axiosConfig);
12
12
  axiosApi.interceptors.request.use((request) => {
13
- if (axiosConfig === null || axiosConfig === void 0 ? void 0 : axiosConfig.logRequests) {
13
+ if (request === null || request === void 0 ? void 0 : request.logRequest) {
14
14
  const { data, params, method } = request;
15
15
  const fullUrl = getFullUrlFromConfig(request);
16
16
  request.meta = request.meta || {};
@@ -21,7 +21,8 @@ function createApi(axiosConfig) {
21
21
  return request;
22
22
  });
23
23
  axiosApi.interceptors.response.use((response) => {
24
- if (axiosConfig === null || axiosConfig === void 0 ? void 0 : axiosConfig.logRequests) {
24
+ var _a;
25
+ if ((_a = response.config) === null || _a === void 0 ? void 0 : _a.logResponse) {
25
26
  const { status, data, config } = response;
26
27
  const { method, meta } = config;
27
28
  const fullUrl = getFullUrlFromConfig(config);
@@ -30,12 +31,10 @@ function createApi(axiosConfig) {
30
31
  }
31
32
  return response;
32
33
  }, (error) => {
33
- if (axiosConfig === null || axiosConfig === void 0 ? void 0 : axiosConfig.logRequests) {
34
- const { config, message, response } = error;
35
- const { method, meta } = config;
36
- const fullUrl = getFullUrlFromConfig(config);
37
- logError(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, response === null || response === void 0 ? void 0 : response.data, response === null || response === void 0 ? void 0 : response.status, message);
38
- }
34
+ const { config, message, response } = error;
35
+ const { method, meta } = config;
36
+ const fullUrl = getFullUrlFromConfig(config);
37
+ logError(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, response === null || response === void 0 ? void 0 : response.data, response === null || response === void 0 ? void 0 : response.status, message);
39
38
  throw error;
40
39
  });
41
40
  return axiosApi;
@@ -0,0 +1,46 @@
1
+ declare type GenericClass<T> = (new (...args: any[]) => T);
2
+ declare type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
3
+ declare type TypesByMethodNames<T> = {
4
+ [K in keyof T]?: T[K] extends (...args: any[]) => infer R ? R : never;
5
+ };
6
+ declare type ResolvedTypesByMethodNames<T> = {
7
+ [K in keyof T]?: T[K] extends (...args: any[]) => infer R ? UnwrapPromise<R> : never;
8
+ };
9
+ /**
10
+ * Creates a mock instance of a given class with customized method implementations,
11
+ * where method return values are automatically unwrapped if they are promises.
12
+ * @example
13
+ * const userRepository = mockResolvedClass(UserRepository, {
14
+ * findUserByToken: { token: 'adhf753', name: 'John' },
15
+ * });
16
+ * @param Class - The class to mock.
17
+ * @param givenMethods - An object containing customized key-value pairs where the key
18
+ * is the method name and the value is the resolved method value.
19
+ * @returns A mocked instance of the provided class with overridden methods.
20
+ */
21
+ export declare function mockResolvedClass<T>(Class: GenericClass<T>, givenMethods?: ResolvedTypesByMethodNames<T>): T;
22
+ /**
23
+ * Creates a mock instance of a given class with customized method implementations.
24
+ * @example
25
+ * const userRepository = mockClass(UserRepository, {
26
+ * findUserByToken: Promise.resolve({ token: 'adhf753', name: 'John' }),
27
+ * });
28
+ * @param Class - The class to mock.
29
+ * @param methods - An object containing customized key-value pairs where the key
30
+ * is the method name and the value is the returned method value.
31
+ * @returns A mocked instance of the provided class with overridden methods.
32
+ */
33
+ export declare function mockClass<T>(Class: GenericClass<T>, givenMethods?: TypesByMethodNames<T>): T;
34
+ /**
35
+ * Creates a raw mock instance of a given class with no method implementations.
36
+ * This function is intended for use with testing frameworks like jest (spyOn) when
37
+ * you want to set up **manual** method spies. Alternatively, consider using
38
+ * {@link mockClass} or {@link mockResolvedClass} for more comprehensive method mocking.
39
+ * @example
40
+ * const rawUserRepository = rawInstance(UserRepository);
41
+ * jest.spyOn(rawUserRepository, 'findUserByToken').mockRejectedValue(new Error('Token expired'));
42
+ * @param Class - The class to mock.
43
+ * @returns A raw mocked instance of the provided class with no implemented methods.
44
+ */
45
+ export declare function rawInstance<T>(Class: GenericClass<T>): T;
46
+ export {};
package/stubs/index.js ADDED
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rawInstance = exports.mockClass = exports.mockResolvedClass = void 0;
4
+ class MockedClassInstance {
5
+ }
6
+ ;
7
+ /**
8
+ * Creates a mock instance of a given class with customized method implementations,
9
+ * where method return values are automatically unwrapped if they are promises.
10
+ * @example
11
+ * const userRepository = mockResolvedClass(UserRepository, {
12
+ * findUserByToken: { token: 'adhf753', name: 'John' },
13
+ * });
14
+ * @param Class - The class to mock.
15
+ * @param givenMethods - An object containing customized key-value pairs where the key
16
+ * is the method name and the value is the resolved method value.
17
+ * @returns A mocked instance of the provided class with overridden methods.
18
+ */
19
+ function mockResolvedClass(Class, givenMethods) {
20
+ const MockedClass = rawInstance(Class);
21
+ if (!givenMethods)
22
+ return MockedClass;
23
+ for (const classMethod in givenMethods) {
24
+ const methodName = classMethod;
25
+ const mockImplementation = () => givenMethods[methodName];
26
+ MockedClass[methodName] = mockImplementation;
27
+ }
28
+ return MockedClass;
29
+ }
30
+ exports.mockResolvedClass = mockResolvedClass;
31
+ /**
32
+ * Creates a mock instance of a given class with customized method implementations.
33
+ * @example
34
+ * const userRepository = mockClass(UserRepository, {
35
+ * findUserByToken: Promise.resolve({ token: 'adhf753', name: 'John' }),
36
+ * });
37
+ * @param Class - The class to mock.
38
+ * @param methods - An object containing customized key-value pairs where the key
39
+ * is the method name and the value is the returned method value.
40
+ * @returns A mocked instance of the provided class with overridden methods.
41
+ */
42
+ function mockClass(Class, givenMethods) {
43
+ const MockedClass = rawInstance(Class);
44
+ if (!givenMethods)
45
+ return MockedClass;
46
+ for (const classMethod in givenMethods) {
47
+ const methodName = classMethod;
48
+ const mockImplementation = () => givenMethods[methodName];
49
+ MockedClass[methodName] = mockImplementation;
50
+ }
51
+ return MockedClass;
52
+ }
53
+ exports.mockClass = mockClass;
54
+ /**
55
+ * Creates a raw mock instance of a given class with no method implementations.
56
+ * This function is intended for use with testing frameworks like jest (spyOn) when
57
+ * you want to set up **manual** method spies. Alternatively, consider using
58
+ * {@link mockClass} or {@link mockResolvedClass} for more comprehensive method mocking.
59
+ * @example
60
+ * const rawUserRepository = rawInstance(UserRepository);
61
+ * jest.spyOn(rawUserRepository, 'findUserByToken').mockRejectedValue(new Error('Token expired'));
62
+ * @param Class - The class to mock.
63
+ * @returns A raw mocked instance of the provided class with no implemented methods.
64
+ */
65
+ function rawInstance(Class) {
66
+ const MockedClass = new MockedClassInstance();
67
+ const classMethods = Object.getOwnPropertyNames(Class.prototype).filter(methodName => methodName !== 'constructor' &&
68
+ typeof Class.prototype[methodName] === 'function');
69
+ for (const classMethod of classMethods) {
70
+ const methodName = classMethod;
71
+ const mockImplementation = () => {
72
+ throw new Error(`Method ${classMethod} not implemented`);
73
+ };
74
+ MockedClass[methodName] = mockImplementation;
75
+ }
76
+ return MockedClass;
77
+ }
78
+ exports.rawInstance = rawInstance;
@@ -1,5 +0,0 @@
1
- import { AxiosRequestConfig } from 'axios';
2
- export interface RequestConfig extends AxiosRequestConfig {
3
- meta?: Record<string, any>;
4
- logRequests?: boolean;
5
- }
package/request/types.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });