@prisma-next/utils 0.0.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.
- package/README.md +88 -0
- package/dist/exports/defined.d.ts +27 -0
- package/dist/exports/defined.js +8 -0
- package/dist/exports/defined.js.map +1 -0
- package/dist/exports/result.d.ts +47 -0
- package/dist/exports/result.js +17 -0
- package/dist/exports/result.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @prisma-next/utils
|
|
2
|
+
|
|
3
|
+
Shared utility functions for Prisma Next.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides general-purpose utility functions used across the Prisma Next codebase. These utilities are target-agnostic and have no dependencies on other Prisma Next packages.
|
|
8
|
+
|
|
9
|
+
## Utilities
|
|
10
|
+
|
|
11
|
+
### `ifDefined(key, value)`
|
|
12
|
+
|
|
13
|
+
Returns an object with the key/value if value is defined, otherwise an empty object. Use with spread to conditionally include optional properties while satisfying `exactOptionalPropertyTypes`.
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
17
|
+
|
|
18
|
+
// Instead of:
|
|
19
|
+
const obj = {
|
|
20
|
+
required: 'value',
|
|
21
|
+
...(optional ? { optional } : {}),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Use:
|
|
25
|
+
const obj = {
|
|
26
|
+
required: 'value',
|
|
27
|
+
...ifDefined('optional', optional),
|
|
28
|
+
};
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Why use this?**
|
|
32
|
+
|
|
33
|
+
1. **Explicit**: You name exactly which properties are optional
|
|
34
|
+
2. **Intentional**: Won't accidentally strip other properties
|
|
35
|
+
3. **Type-safe**: Returns `{}` or `{ key: V }` (without undefined)
|
|
36
|
+
4. **exactOptionalPropertyTypes compatible**: Properly handles TypeScript's strict optional property checking
|
|
37
|
+
|
|
38
|
+
### `Result<T, F>`, `ok()`, `notOk()`, `okVoid()`
|
|
39
|
+
|
|
40
|
+
Generic Result type for representing success or failure outcomes. This is the standard way to return "expected failures" as values rather than throwing exceptions.
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { type Result, ok, notOk, okVoid } from '@prisma-next/utils/result';
|
|
44
|
+
|
|
45
|
+
// Success result with value
|
|
46
|
+
function divide(a: number, b: number): Result<number, string> {
|
|
47
|
+
if (b === 0) {
|
|
48
|
+
return notOk('Division by zero');
|
|
49
|
+
}
|
|
50
|
+
return ok(a / b);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Using the result
|
|
54
|
+
const result = divide(10, 2);
|
|
55
|
+
if (result.ok) {
|
|
56
|
+
console.log(result.value); // 5
|
|
57
|
+
} else {
|
|
58
|
+
console.error(result.failure); // error message
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Void success for validation
|
|
62
|
+
function validate(value: unknown): Result<void, string> {
|
|
63
|
+
if (!value) {
|
|
64
|
+
return notOk('Value is required');
|
|
65
|
+
}
|
|
66
|
+
return okVoid();
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Types:**
|
|
71
|
+
- `Ok<T>` - Success with value: `{ ok: true, value: T }`
|
|
72
|
+
- `NotOk<F>` - Failure with details: `{ ok: false, failure: F }`
|
|
73
|
+
- `Result<T, F>` - Discriminated union of `Ok<T> | NotOk<F>`
|
|
74
|
+
|
|
75
|
+
See `docs/Error Handling.md` for the full error taxonomy.
|
|
76
|
+
|
|
77
|
+
## Package Location
|
|
78
|
+
|
|
79
|
+
This package is part of the **framework domain**, **core layer**, **shared plane**:
|
|
80
|
+
- **Domain**: framework (target-agnostic)
|
|
81
|
+
- **Layer**: core
|
|
82
|
+
- **Plane**: shared
|
|
83
|
+
- **Path**: `packages/1-framework/1-core/shared/utils`
|
|
84
|
+
|
|
85
|
+
## Dependencies
|
|
86
|
+
|
|
87
|
+
This package has **no dependencies** - it's part of the innermost core ring and provides foundational utilities.
|
|
88
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an object with the key/value if value is defined, otherwise an empty object.
|
|
3
|
+
*
|
|
4
|
+
* Use with spread to conditionally include optional properties while satisfying
|
|
5
|
+
* exactOptionalPropertyTypes. This is explicit about which properties are optional
|
|
6
|
+
* and won't inadvertently strip other undefined values.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Instead of:
|
|
11
|
+
* const obj = {
|
|
12
|
+
* required: 'value',
|
|
13
|
+
* ...(optional ? { optional } : {}),
|
|
14
|
+
* };
|
|
15
|
+
*
|
|
16
|
+
* // Use:
|
|
17
|
+
* const obj = {
|
|
18
|
+
* required: 'value',
|
|
19
|
+
* ...ifDefined('optional', optional),
|
|
20
|
+
* };
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare function ifDefined<K extends string, V>(key: K, value: V | undefined): Record<never, never> | {
|
|
24
|
+
[P in K]: V;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { ifDefined };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/defined.ts"],"sourcesContent":["/**\n * Returns an object with the key/value if value is defined, otherwise an empty object.\n *\n * Use with spread to conditionally include optional properties while satisfying\n * exactOptionalPropertyTypes. This is explicit about which properties are optional\n * and won't inadvertently strip other undefined values.\n *\n * @example\n * ```typescript\n * // Instead of:\n * const obj = {\n * required: 'value',\n * ...(optional ? { optional } : {}),\n * };\n *\n * // Use:\n * const obj = {\n * required: 'value',\n * ...ifDefined('optional', optional),\n * };\n * ```\n */\nexport function ifDefined<K extends string, V>(\n key: K,\n value: V | undefined,\n): Record<never, never> | { [P in K]: V } {\n return value !== undefined ? ({ [key]: value } as { [P in K]: V }) : {};\n}\n"],"mappings":";AAsBO,SAAS,UACd,KACA,OACwC;AACxC,SAAO,UAAU,SAAa,EAAE,CAAC,GAAG,GAAG,MAAM,IAAwB,CAAC;AACxE;","names":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Result type for representing success or failure outcomes.
|
|
3
|
+
*
|
|
4
|
+
* This is the standard way to return "expected failures" as values rather than
|
|
5
|
+
* throwing exceptions. See docs/Error Handling.md for the full taxonomy.
|
|
6
|
+
*
|
|
7
|
+
* Naming rationale:
|
|
8
|
+
* - `Ok<T>` / `NotOk<F>` mirror the `ok: true/false` discriminator
|
|
9
|
+
* - `NotOk` avoids collision with domain types like "Failure" or "Error"
|
|
10
|
+
* - `failure` property distinguishes from JS Error semantics
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Represents a successful result containing a value.
|
|
14
|
+
*/
|
|
15
|
+
interface Ok<T> {
|
|
16
|
+
readonly ok: true;
|
|
17
|
+
readonly value: T;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Represents an unsuccessful result containing failure details.
|
|
21
|
+
*/
|
|
22
|
+
interface NotOk<F> {
|
|
23
|
+
readonly ok: false;
|
|
24
|
+
readonly failure: F;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A discriminated union representing either success (Ok) or failure (NotOk).
|
|
28
|
+
*
|
|
29
|
+
* @typeParam T - The success value type
|
|
30
|
+
* @typeParam F - The failure details type
|
|
31
|
+
*/
|
|
32
|
+
type Result<T, F> = Ok<T> | NotOk<F>;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a successful result.
|
|
35
|
+
*/
|
|
36
|
+
declare function ok<T>(value: T): Ok<T>;
|
|
37
|
+
/**
|
|
38
|
+
* Creates an unsuccessful result.
|
|
39
|
+
*/
|
|
40
|
+
declare function notOk<F>(failure: F): NotOk<F>;
|
|
41
|
+
/**
|
|
42
|
+
* Returns a successful void result.
|
|
43
|
+
* Use this for validation checks that don't produce a value.
|
|
44
|
+
*/
|
|
45
|
+
declare function okVoid(): Ok<void>;
|
|
46
|
+
|
|
47
|
+
export { type NotOk, type Ok, type Result, notOk, ok, okVoid };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/result.ts
|
|
2
|
+
function ok(value) {
|
|
3
|
+
return Object.freeze({ ok: true, value });
|
|
4
|
+
}
|
|
5
|
+
function notOk(failure) {
|
|
6
|
+
return Object.freeze({ ok: false, failure });
|
|
7
|
+
}
|
|
8
|
+
var OK_VOID = Object.freeze({ ok: true, value: void 0 });
|
|
9
|
+
function okVoid() {
|
|
10
|
+
return OK_VOID;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
notOk,
|
|
14
|
+
ok,
|
|
15
|
+
okVoid
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/result.ts"],"sourcesContent":["/**\n * Generic Result type for representing success or failure outcomes.\n *\n * This is the standard way to return \"expected failures\" as values rather than\n * throwing exceptions. See docs/Error Handling.md for the full taxonomy.\n *\n * Naming rationale:\n * - `Ok<T>` / `NotOk<F>` mirror the `ok: true/false` discriminator\n * - `NotOk` avoids collision with domain types like \"Failure\" or \"Error\"\n * - `failure` property distinguishes from JS Error semantics\n */\n\n/**\n * Represents a successful result containing a value.\n */\nexport interface Ok<T> {\n readonly ok: true;\n readonly value: T;\n}\n\n/**\n * Represents an unsuccessful result containing failure details.\n */\nexport interface NotOk<F> {\n readonly ok: false;\n readonly failure: F;\n}\n\n/**\n * A discriminated union representing either success (Ok) or failure (NotOk).\n *\n * @typeParam T - The success value type\n * @typeParam F - The failure details type\n */\nexport type Result<T, F> = Ok<T> | NotOk<F>;\n\n/**\n * Creates a successful result.\n */\nexport function ok<T>(value: T): Ok<T> {\n return Object.freeze({ ok: true, value });\n}\n\n/**\n * Creates an unsuccessful result.\n */\nexport function notOk<F>(failure: F): NotOk<F> {\n return Object.freeze({ ok: false, failure });\n}\n\n/**\n * Singleton for void success results.\n * Use this for validation checks that don't produce a value.\n */\nconst OK_VOID: Ok<void> = Object.freeze({ ok: true, value: undefined });\n\n/**\n * Returns a successful void result.\n * Use this for validation checks that don't produce a value.\n */\nexport function okVoid(): Ok<void> {\n return OK_VOID;\n}\n"],"mappings":";AAuCO,SAAS,GAAM,OAAiB;AACrC,SAAO,OAAO,OAAO,EAAE,IAAI,MAAM,MAAM,CAAC;AAC1C;AAKO,SAAS,MAAS,SAAsB;AAC7C,SAAO,OAAO,OAAO,EAAE,IAAI,OAAO,QAAQ,CAAC;AAC7C;AAMA,IAAM,UAAoB,OAAO,OAAO,EAAE,IAAI,MAAM,OAAO,OAAU,CAAC;AAM/D,SAAS,SAAmB;AACjC,SAAO;AACT;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prisma-next/utils",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "Shared utility functions for Prisma Next",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@vitest/coverage-v8": "^2.1.1",
|
|
9
|
+
"tsup": "^8.3.0",
|
|
10
|
+
"typescript": "^5.9.3",
|
|
11
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
12
|
+
"vitest": "^2.1.1"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"exports": {
|
|
18
|
+
"./defined": {
|
|
19
|
+
"types": "./dist/exports/defined.d.ts",
|
|
20
|
+
"import": "./dist/exports/defined.js"
|
|
21
|
+
},
|
|
22
|
+
"./result": {
|
|
23
|
+
"types": "./dist/exports/result.d.ts",
|
|
24
|
+
"import": "./dist/exports/result.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup --config tsup.config.ts",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:coverage": "vitest run --coverage",
|
|
31
|
+
"typecheck": "tsc --project tsconfig.json --noEmit",
|
|
32
|
+
"lint": "biome check . --config-path ../../../../../biome.json --error-on-warnings",
|
|
33
|
+
"clean": "node ../../../../../scripts/clean.mjs"
|
|
34
|
+
}
|
|
35
|
+
}
|