@backendkit-labs/result 0.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.
@@ -0,0 +1,114 @@
1
+ import { Injectable, Module } from '@nestjs/common';
2
+ import { map } from 'rxjs/operators';
3
+
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __decorateClass = (decorators, target, key, kind) => {
6
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
7
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
8
+ if (decorator = decorators[i])
9
+ result = (decorator(result)) || result;
10
+ return result;
11
+ };
12
+
13
+ // src/result/constructors.ts
14
+ var ok = (value) => ({ ok: true, value });
15
+ var fail = (error) => ({ ok: false, error });
16
+
17
+ // src/result/run.ts
18
+ async function run(fn, errorTransform) {
19
+ try {
20
+ return ok(await fn());
21
+ } catch (caught) {
22
+ return fail(caught);
23
+ }
24
+ }
25
+ async function track(fn, options) {
26
+ const start = performance.now();
27
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
28
+ const meta = {
29
+ durationMs: 0,
30
+ timestamp,
31
+ operation: options?.operation,
32
+ correlationId: options?.correlationId,
33
+ tags: options?.tags
34
+ };
35
+ try {
36
+ const value = await fn();
37
+ return { ok: true, value, ...meta, durationMs: Math.round(performance.now() - start) };
38
+ } catch (caught) {
39
+ const error = options?.errorTransform ? options.errorTransform(caught) : caught;
40
+ return { ok: false, error, ...meta, durationMs: Math.round(performance.now() - start) };
41
+ }
42
+ }
43
+
44
+ // src/nestjs/decorators.ts
45
+ function AsResult(operation) {
46
+ return function(_target, _key, descriptor) {
47
+ const original = descriptor.value;
48
+ descriptor.value = async function(...args) {
49
+ return run(
50
+ () => original.apply(this, args));
51
+ };
52
+ if (operation) {
53
+ descriptor.value.operationName = operation;
54
+ }
55
+ return descriptor;
56
+ };
57
+ }
58
+ function WithMetrics(options) {
59
+ const opts = typeof options === "string" ? { operation: options } : options ?? {};
60
+ return function(_target, _key, descriptor) {
61
+ const original = descriptor.value;
62
+ descriptor.value = async function(...args) {
63
+ return track(() => original.apply(this, args), opts);
64
+ };
65
+ return descriptor;
66
+ };
67
+ }
68
+
69
+ // src/result/guards.ts
70
+ function isRich(result) {
71
+ return "durationMs" in result;
72
+ }
73
+
74
+ // src/nestjs/interceptor.ts
75
+ function isResult(value) {
76
+ return typeof value === "object" && value !== null && "ok" in value && typeof value["ok"] === "boolean";
77
+ }
78
+ var ResultInterceptor = class {
79
+ intercept(_ctx, next) {
80
+ return next.handle().pipe(
81
+ map((value) => {
82
+ if (!isResult(value)) return value;
83
+ const base = value.ok ? { ok: true, data: value.value } : { ok: false, error: String(value.error) };
84
+ if (!isRich(value)) return base;
85
+ const rich = value;
86
+ return {
87
+ ...base,
88
+ meta: {
89
+ ...rich.operation ? { operation: rich.operation } : {},
90
+ ...rich.correlationId ? { correlationId: rich.correlationId } : {},
91
+ ...rich.tags?.length ? { tags: rich.tags } : {},
92
+ durationMs: rich.durationMs,
93
+ timestamp: rich.timestamp
94
+ }
95
+ };
96
+ })
97
+ );
98
+ }
99
+ };
100
+ ResultInterceptor = __decorateClass([
101
+ Injectable()
102
+ ], ResultInterceptor);
103
+ var ResultModule = class {
104
+ };
105
+ ResultModule = __decorateClass([
106
+ Module({
107
+ providers: [ResultInterceptor],
108
+ exports: [ResultInterceptor]
109
+ })
110
+ ], ResultModule);
111
+
112
+ export { AsResult, ResultInterceptor, ResultModule, WithMetrics };
113
+ //# sourceMappingURL=index.js.map
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/result/constructors.ts","../../src/result/run.ts","../../src/nestjs/decorators.ts","../../src/result/guards.ts","../../src/nestjs/interceptor.ts","../../src/nestjs/module.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Result } from './types.js';\n\n/** Creates a successful Result. */\nexport const ok = <T, E = never>(value: T): Result<T, E> =>\n ({ ok: true, value });\n\n/** Creates a failed Result. */\nexport const fail = <T = never, E = Error>(error: E): Result<T, E> =>\n ({ ok: false, error });\n\n/**\n * Wraps a synchronous throwable function. Catches any thrown value and\n * passes it through `errorTransform` (defaults to identity cast).\n *\n * @example\n * const result = fromThrowable(() => JSON.parse(raw), (e) => new ParseError(e));\n */\nexport function fromThrowable<T, E = Error>(\n fn: () => T,\n errorTransform?: (caught: unknown) => E,\n): Result<T, E> {\n try {\n return ok(fn());\n } catch (caught) {\n return fail(errorTransform ? errorTransform(caught) : (caught as E));\n }\n}\n\n/**\n * Converts a Promise to a `Promise<Result<T, E>>`, catching rejections.\n *\n * @example\n * const result = await fromPromise(fetch(url), (e) => new NetworkError(e));\n */\nexport async function fromPromise<T, E = Error>(\n promise: Promise<T>,\n errorTransform?: (caught: unknown) => E,\n): Promise<Result<T, E>> {\n try {\n return ok(await promise);\n } catch (caught) {\n return fail(errorTransform ? errorTransform(caught) : (caught as E));\n }\n}\n\n/**\n * Converts a nullable value to a Result.\n * Returns `ok(value)` if non-null/undefined, `fail(error)` otherwise.\n *\n * @example\n * const result = fromNullable(user, new NotFoundError('user'));\n */\nexport function fromNullable<T, E>(\n value: T | null | undefined,\n error: E,\n): Result<T, E> {\n return value != null ? ok(value) : fail(error);\n}\n","import type { Result, RichResult, TrackOptions } from './types.js';\nimport { ok, fail } from './constructors.js';\n\n/**\n * Executes an async (or sync) function and captures any thrown exception,\n * returning a `Result<T, E>` instead of propagating the error.\n *\n * @example\n * const result = await run(() => fetchUser(id));\n * const result = await run(() => fetchUser(id), (e) => new UserError(e));\n */\nexport async function run<T, E = Error>(\n fn: () => T | Promise<T>,\n errorTransform?: (caught: unknown) => E,\n): Promise<Result<T, E>> {\n try {\n return ok(await fn());\n } catch (caught) {\n return fail(errorTransform ? errorTransform(caught) : (caught as E));\n }\n}\n\n/**\n * Like `run()` but also captures timing and metadata, returning a `RichResult<T, E>`.\n *\n * @example\n * const result = await track(() => fetchUser(id), { operation: 'user.fetch', tags: ['db'] });\n */\nexport async function track<T, E = Error>(\n fn: () => T | Promise<T>,\n options?: TrackOptions & { errorTransform?: (caught: unknown) => E },\n): Promise<RichResult<T, E>> {\n const start = performance.now();\n const timestamp = new Date().toISOString();\n const meta = {\n durationMs: 0,\n timestamp,\n operation: options?.operation,\n correlationId: options?.correlationId,\n tags: options?.tags,\n };\n\n try {\n const value = await fn();\n return { ok: true, value, ...meta, durationMs: Math.round(performance.now() - start) };\n } catch (caught) {\n const error = options?.errorTransform ? options.errorTransform(caught) : (caught as E);\n return { ok: false, error, ...meta, durationMs: Math.round(performance.now() - start) };\n }\n}\n\n/**\n * Promotes a plain `Result<T, E>` to a `RichResult<T, E>` with a zero-duration snapshot.\n * Useful when you already have a Result and want to attach metadata.\n */\nexport function enrich<T, E>(result: Result<T, E>, options?: TrackOptions): RichResult<T, E> {\n return {\n ...result,\n durationMs: 0,\n timestamp: new Date().toISOString(),\n operation: options?.operation,\n correlationId: options?.correlationId,\n tags: options?.tags,\n };\n}\n\n/**\n * Strips observability metadata from a `RichResult`, returning a plain `Result<T, E>`.\n */\nexport function simplify<T, E>(rich: RichResult<T, E>): Result<T, E> {\n return rich.ok\n ? { ok: true, value: rich.value }\n : { ok: false, error: rich.error };\n}\n","import { run, track } from '../result/run.js';\nimport type { TrackOptions } from '../result/types.js';\n\n/**\n * Method decorator that wraps the return value in `run()`, converting any\n * thrown exception into a `Result<T, E>`.\n *\n * @example\n * @AsResult('user.find')\n * async findUser(id: string) {\n * return this.db.users.findOrThrow(id);\n * }\n */\nexport function AsResult(operation?: string) {\n return function (\n _target: unknown,\n _key: string,\n descriptor: PropertyDescriptor,\n ): PropertyDescriptor {\n const original = descriptor.value as (...args: unknown[]) => unknown;\n descriptor.value = async function (...args: unknown[]) {\n return run(\n () => original.apply(this, args) as Promise<unknown>,\n undefined,\n );\n };\n if (operation) {\n (descriptor.value as { operationName?: string }).operationName = operation;\n }\n return descriptor;\n };\n}\n\n/**\n * Method decorator that wraps the return value in `track()`, capturing\n * execution duration, timestamp, and optional metadata.\n *\n * @example\n * @WithMetrics({ operation: 'payment.charge', tags: ['stripe'] })\n * async charge(dto: ChargeDto) {\n * return this.stripe.charge(dto);\n * }\n */\nexport function WithMetrics(options?: string | TrackOptions) {\n const opts: TrackOptions =\n typeof options === 'string' ? { operation: options } : (options ?? {});\n\n return function (\n _target: unknown,\n _key: string,\n descriptor: PropertyDescriptor,\n ): PropertyDescriptor {\n const original = descriptor.value as (...args: unknown[]) => unknown;\n descriptor.value = async function (...args: unknown[]) {\n return track(() => original.apply(this, args) as Promise<unknown>, opts);\n };\n return descriptor;\n };\n}\n","import type { Result, RichResult } from './types.js';\n\ntype OkResult<T, E> = Extract<Result<T, E>, { ok: true }>;\ntype FailResult<T, E> = Extract<Result<T, E>, { ok: false }>;\n\n/** Narrows a `Result<T, E>` to its success branch. */\nexport function isOk<T, E>(result: Result<T, E>): result is OkResult<T, E> {\n return result.ok === true;\n}\n\n/** Narrows a `Result<T, E>` to its failure branch. */\nexport function isFail<T, E>(result: Result<T, E>): result is FailResult<T, E> {\n return result.ok === false;\n}\n\n/** Returns `true` if the result carries observability metadata (`track()` output). */\nexport function isRich<T, E>(result: Result<T, E>): result is RichResult<T, E> {\n return 'durationMs' in result;\n}\n","import {\n Injectable,\n NestInterceptor,\n ExecutionContext,\n CallHandler,\n} from '@nestjs/common';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport type { Result, RichResult } from '../result/types.js';\nimport { isRich } from '../result/guards.js';\n\nfunction isResult(value: unknown): value is Result<unknown, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'ok' in value &&\n typeof (value as Record<string, unknown>)['ok'] === 'boolean'\n );\n}\n\n/**\n * Transforms `Result<T, E>` and `RichResult<T, E>` return values into a\n * consistent JSON response shape, so controllers don't need to unwrap manually.\n *\n * Plain results:\n * ```json\n * { \"ok\": true, \"data\": <value> }\n * { \"ok\": false, \"error\": \"<string>\" }\n * ```\n *\n * Rich results also include a `meta` block:\n * ```json\n * { \"ok\": true, \"data\": <value>, \"meta\": { \"operation\": \"...\", \"durationMs\": 12, ... } }\n * ```\n *\n * Non-Result return values are passed through unchanged.\n *\n * @example\n * // Global\n * app.useGlobalInterceptors(app.get(ResultInterceptor));\n *\n * // Per-controller\n * @UseInterceptors(ResultInterceptor)\n * @Controller('users')\n * export class UsersController { ... }\n */\n@Injectable()\nexport class ResultInterceptor implements NestInterceptor {\n intercept(_ctx: ExecutionContext, next: CallHandler): Observable<unknown> {\n return next.handle().pipe(\n map(value => {\n if (!isResult(value)) return value;\n\n const base = value.ok\n ? { ok: true, data: (value as { value: unknown }).value }\n : { ok: false, error: String((value as { error: unknown }).error) };\n\n if (!isRich(value)) return base;\n\n const rich = value as RichResult<unknown, unknown>;\n return {\n ...base,\n meta: {\n ...(rich.operation ? { operation: rich.operation } : {}),\n ...(rich.correlationId ? { correlationId: rich.correlationId } : {}),\n ...(rich.tags?.length ? { tags: rich.tags } : {}),\n durationMs: rich.durationMs,\n timestamp: rich.timestamp,\n },\n };\n }),\n );\n }\n}\n","import { Module } from '@nestjs/common';\nimport { ResultInterceptor } from './interceptor.js';\n\n@Module({\n providers: [ResultInterceptor],\n exports: [ResultInterceptor],\n})\nexport class ResultModule {}\n"]}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A discriminated union representing either a successful value (`ok: true`)
3
+ * or a failure (`ok: false`). The error type `E` is fully generic.
4
+ *
5
+ * @example
6
+ * function findUser(id: string): Result<User, 'not-found' | 'db-error'> { ... }
7
+ */
8
+ type Result<T, E = Error> = {
9
+ readonly ok: true;
10
+ readonly value: T;
11
+ } | {
12
+ readonly ok: false;
13
+ readonly error: E;
14
+ };
15
+ /**
16
+ * A Result extended with observability metadata captured at execution time.
17
+ * Produced by `track()` and `job()`.
18
+ */
19
+ type RichResult<T, E = Error> = Result<T, E> & {
20
+ readonly durationMs: number;
21
+ readonly timestamp: string;
22
+ readonly operation?: string;
23
+ readonly correlationId?: string;
24
+ readonly tags?: string[];
25
+ };
26
+ /** Options for enriching a Result with observability metadata. */
27
+ interface TrackOptions {
28
+ operation?: string;
29
+ correlationId?: string;
30
+ tags?: string[];
31
+ }
32
+
33
+ export type { Result as R, TrackOptions as T, RichResult as a };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A discriminated union representing either a successful value (`ok: true`)
3
+ * or a failure (`ok: false`). The error type `E` is fully generic.
4
+ *
5
+ * @example
6
+ * function findUser(id: string): Result<User, 'not-found' | 'db-error'> { ... }
7
+ */
8
+ type Result<T, E = Error> = {
9
+ readonly ok: true;
10
+ readonly value: T;
11
+ } | {
12
+ readonly ok: false;
13
+ readonly error: E;
14
+ };
15
+ /**
16
+ * A Result extended with observability metadata captured at execution time.
17
+ * Produced by `track()` and `job()`.
18
+ */
19
+ type RichResult<T, E = Error> = Result<T, E> & {
20
+ readonly durationMs: number;
21
+ readonly timestamp: string;
22
+ readonly operation?: string;
23
+ readonly correlationId?: string;
24
+ readonly tags?: string[];
25
+ };
26
+ /** Options for enriching a Result with observability metadata. */
27
+ interface TrackOptions {
28
+ operation?: string;
29
+ correlationId?: string;
30
+ tags?: string[];
31
+ }
32
+
33
+ export type { Result as R, TrackOptions as T, RichResult as a };
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@backendkit-labs/result",
3
+ "version": "0.1.0",
4
+ "description": "Type-safe Result monad for Node.js — generic error types, observability, resilience, and optional NestJS integration",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./nestjs": {
16
+ "types": "./dist/nestjs/index.d.ts",
17
+ "import": "./dist/nestjs/index.js",
18
+ "require": "./dist/nestjs/index.cjs"
19
+ }
20
+ },
21
+ "files": ["dist", "README.md", "LICENSE"],
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "dev": "tsup --watch",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest",
27
+ "test:coverage": "vitest run --coverage",
28
+ "typecheck": "tsc --noEmit",
29
+ "lint": "eslint src/",
30
+ "prepublishOnly": "npm run build && npm run test && npm run lint"
31
+ },
32
+ "keywords": [
33
+ "result", "either", "monad", "error-handling",
34
+ "functional", "railway", "nestjs", "typescript", "node"
35
+ ],
36
+ "author": "Mairon José Cuello Martínez",
37
+ "license": "MIT",
38
+ "homepage": "https://github.com/backendkit-dev/backendkit-monorepo/tree/master/packages/result#readme",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/backendkit-dev/backendkit-monorepo.git",
42
+ "directory": "packages/result"
43
+ },
44
+ "bugs": { "url": "https://github.com/backendkit-dev/backendkit-monorepo/issues" },
45
+ "sideEffects": false,
46
+ "engines": { "node": ">=18" },
47
+ "peerDependencies": {
48
+ "@nestjs/common": ">=10.0.0",
49
+ "@nestjs/core": ">=10.0.0",
50
+ "rxjs": ">=7.0.0"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "@nestjs/common": { "optional": true },
54
+ "@nestjs/core": { "optional": true },
55
+ "rxjs": { "optional": true }
56
+ },
57
+ "devDependencies": {
58
+ "@eslint/js": "^9.39.4",
59
+ "@nestjs/common": "^10.0.0",
60
+ "@nestjs/core": "^10.0.0",
61
+ "@types/node": "^22.0.0",
62
+ "eslint": "^9.0.0",
63
+ "reflect-metadata": "^0.2.0",
64
+ "rxjs": "^7.8.0",
65
+ "tsup": "^8.0.0",
66
+ "typescript": "^5.5.0",
67
+ "typescript-eslint": "^8.59.3",
68
+ "vitest": "^2.0.0"
69
+ }
70
+ }