@dvsa/appdev-api-common 0.7.0 → 0.8.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.
@@ -0,0 +1,7 @@
1
+ import type { Logger } from "@aws-lambda-powertools/logger";
2
+ export declare function LogDurationWithAccessor<T extends {
3
+ logger: Logger;
4
+ }>(getLogger: (self: T) => Logger, label?: string): (_target: unknown, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
5
+ export declare function Timed<T extends {
6
+ logger: Logger;
7
+ }>(label?: string): (_target: unknown, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogDurationWithAccessor = LogDurationWithAccessor;
4
+ exports.Timed = Timed;
5
+ const node_perf_hooks_1 = require("node:perf_hooks");
6
+ function LogDurationWithAccessor(getLogger, label) {
7
+ return (_target, propertyKey, descriptor) => {
8
+ const originalMethod = descriptor.value;
9
+ // biome-ignore lint/suspicious/noExplicitAny: "any" is correct for this context
10
+ descriptor.value = function (...args) {
11
+ const logger = getLogger(this);
12
+ const labelToUse = label || propertyKey;
13
+ const start = node_perf_hooks_1.performance.now();
14
+ try {
15
+ const result = originalMethod.apply(this, args);
16
+ // async route, if it's a Promise.
17
+ if (result instanceof Promise) {
18
+ return result
19
+ .then((res) => {
20
+ const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2);
21
+ logger.debug(`[${labelToUse}] took ${duration}ms`);
22
+ return res;
23
+ })
24
+ .catch((err) => {
25
+ const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2);
26
+ logger.debug(`[${labelToUse}] failed after ${duration}ms`);
27
+ throw err;
28
+ });
29
+ }
30
+ // Otherwise, sync method: log and return
31
+ const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2);
32
+ logger.debug(`[${labelToUse}] took ${duration}ms`);
33
+ return result;
34
+ }
35
+ catch (err) {
36
+ const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2);
37
+ logger.debug(`[${labelToUse}] failed after ${duration}ms`);
38
+ throw err;
39
+ }
40
+ };
41
+ return descriptor;
42
+ };
43
+ }
44
+ function Timed(label) {
45
+ return LogDurationWithAccessor((cls) => {
46
+ if (!cls.logger) {
47
+ throw new Error(`[${label}] Logger not found on decorated class.`);
48
+ }
49
+ return cls.logger;
50
+ }, label);
51
+ }
@@ -0,0 +1,10 @@
1
+ export declare class HTTPError extends Error {
2
+ response: Response;
3
+ constructor(message: string, response: Response);
4
+ }
5
+ export declare class HTTP {
6
+ static get(url: string, options?: RequestInit): Promise<Response>;
7
+ static post<T>(url: string, body: T, options?: RequestInit): Promise<Response>;
8
+ static put<T>(url: string, body: T, options?: RequestInit): Promise<Response>;
9
+ static delete(url: string, options?: RequestInit): Promise<Response>;
10
+ }
package/http/index.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HTTP = exports.HTTPError = void 0;
4
+ class HTTPError extends Error {
5
+ response;
6
+ constructor(message, response) {
7
+ super(message);
8
+ this.response = response;
9
+ this.name = "HTTPError";
10
+ this.response = response;
11
+ }
12
+ }
13
+ exports.HTTPError = HTTPError;
14
+ // biome-ignore lint/complexity/noStaticOnlyClass: makes sense for an HTTP utility to encompass all methods
15
+ class HTTP {
16
+ static async get(url, options) {
17
+ const response = await fetch(url, { method: "GET", ...options });
18
+ if (!response.ok) {
19
+ throw new HTTPError(`HTTP GET request failed with status ${response.status}`, response);
20
+ }
21
+ return response;
22
+ }
23
+ static async post(url, body, options) {
24
+ const response = await fetch(url, {
25
+ method: "POST",
26
+ headers: { "Content-Type": "application/json", ...options?.headers },
27
+ body: JSON.stringify(body),
28
+ ...options,
29
+ });
30
+ if (!response.ok) {
31
+ throw new HTTPError(`HTTP POST request failed with status ${response.status}`, response);
32
+ }
33
+ return response;
34
+ }
35
+ static async put(url, body, options) {
36
+ const response = await fetch(url, {
37
+ method: "PUT",
38
+ headers: { "Content-Type": "application/json", ...options?.headers },
39
+ body: JSON.stringify(body),
40
+ ...options,
41
+ });
42
+ if (!response.ok) {
43
+ throw new HTTPError(`HTTP PUT request failed with status ${response.status}`, response);
44
+ }
45
+ return response;
46
+ }
47
+ static async delete(url, options) {
48
+ const response = await fetch(url, { method: "DELETE", ...options });
49
+ if (!response.ok) {
50
+ throw new HTTPError(`HTTP DELETE request failed with status ${response.status}`, response);
51
+ }
52
+ return response;
53
+ }
54
+ }
55
+ exports.HTTP = HTTP;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvsa/appdev-api-common",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "keywords": ["dvsa", "nodejs", "typescript"],
5
5
  "author": "DVSA",
6
6
  "description": "Utils library for common API functionality",
@@ -29,6 +29,7 @@
29
29
  "jose": "^5.9.6"
30
30
  },
31
31
  "devDependencies": {
32
+ "@aws-lambda-powertools/logger": "^2.22.0",
32
33
  "@biomejs/biome": "1.9.3",
33
34
  "@dvsa/biome-config": "0.3.0",
34
35
  "@types/aws-lambda": "^8.10.145",