@ultimat3/entity 9.0.0 → 10.0.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/package.json +5 -5
- package/src/entity.ts +8 -3
- package/src/errors.ts +8 -1
- package/src/view.ts +5 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/entity",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "A table + its domain type + invariants the database also enforces",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"test": "bun test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ultimat3/core": "
|
|
35
|
-
"@ultimat3/db": "
|
|
36
|
-
"@ultimat3/schema": "
|
|
37
|
-
"@ultimat3/time": "
|
|
34
|
+
"@ultimat3/core": "10.0.0",
|
|
35
|
+
"@ultimat3/db": "10.0.0",
|
|
36
|
+
"@ultimat3/schema": "10.0.0",
|
|
37
|
+
"@ultimat3/time": "10.0.0"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/entity.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// (the typed db handle, migrations, cache tags, the admin UI, the manifest) is projected from
|
|
4
4
|
// this one call.
|
|
5
5
|
|
|
6
|
+
import { renderThrowable } from '@ultimat3/core';
|
|
6
7
|
import { describeValue, type StandardSchemaV1 } from '@ultimat3/schema';
|
|
7
8
|
import { entityNow } from './clock';
|
|
8
9
|
import { assertColumnName, bindColumn, columnName, moneyColumns } from './column';
|
|
@@ -284,9 +285,13 @@ export const entity = <const C extends ColumnMap>(
|
|
|
284
285
|
try {
|
|
285
286
|
return { value: parse(value) };
|
|
286
287
|
} catch (error) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
// `renderThrowable`, never `error instanceof Error ? error.message : String(error)`:
|
|
289
|
+
// both halves of that read the caught value directly. `instanceof` consults
|
|
290
|
+
// `getPrototypeOf` and `String()` runs the value's own coercion, so a `Proxy` or a
|
|
291
|
+
// null-prototype throwable raised a SECOND, uncatchable `TypeError` out of the
|
|
292
|
+
// validator — where a rejection belongs. A column parser is app-reachable and an
|
|
293
|
+
// app's `$parse` may throw anything at all.
|
|
294
|
+
return { issues: [{ message: renderThrowable(error) }] };
|
|
290
295
|
}
|
|
291
296
|
},
|
|
292
297
|
},
|
package/src/errors.ts
CHANGED
|
@@ -61,6 +61,14 @@ registerErrorCodes(
|
|
|
61
61
|
Object.fromEntries(Object.entries(ENTITY_ERROR_TITLES).map(([code, title]) => [code, { title }])),
|
|
62
62
|
);
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Base for every error this package throws. No `docs:` — `UltimateError` fills it from
|
|
66
|
+
* `describeErrorCode(code).docs`, which is `@ultimat3/core`'s `ERROR_DOCS_URL`: one page for every
|
|
67
|
+
* code, never one per code, because `wiki/` is the framework's only public documentation surface
|
|
68
|
+
* and a code lives there in a TABLE ROW, which has no anchor. The
|
|
69
|
+
* `https://ultimate.dev/errors/<code>` links this class built until 9.x answered 404, host
|
|
70
|
+
* included, on every refusal it has ever raised.
|
|
71
|
+
*/
|
|
64
72
|
export class EntityError extends UltimateError {
|
|
65
73
|
override readonly name = 'EntityError';
|
|
66
74
|
|
|
@@ -69,7 +77,6 @@ export class EntityError extends UltimateError {
|
|
|
69
77
|
code: init.code,
|
|
70
78
|
cause: init.cause,
|
|
71
79
|
fix: init.fix,
|
|
72
|
-
docs: `https://ultimate.dev/errors/${init.code}`,
|
|
73
80
|
});
|
|
74
81
|
}
|
|
75
82
|
}
|
package/src/view.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// already describe. Values are validated by the entity's own column parsers; an unknown key is a
|
|
4
4
|
// declaration-time failure, not a surprise on the first request.
|
|
5
5
|
|
|
6
|
+
import { renderThrowable } from '@ultimat3/core';
|
|
6
7
|
import { describeValue, type StandardSchemaV1 } from '@ultimat3/schema';
|
|
7
8
|
import { invariantViolated } from './errors';
|
|
8
9
|
import type { AnyColumn, ColumnMap } from './types';
|
|
@@ -83,9 +84,10 @@ export const viewFor = <Row, K extends keyof Row & string>(
|
|
|
83
84
|
try {
|
|
84
85
|
return { value: parse(value) };
|
|
85
86
|
} catch (error) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
// The entity's rule, for the same reason: `instanceof` and `String()` are both reads of
|
|
88
|
+
// a caught value, and a throwable that fights being read turned a rejected projection
|
|
89
|
+
// into an uncatchable `TypeError`. `renderThrowable` is total.
|
|
90
|
+
return { issues: [{ message: renderThrowable(error) }] };
|
|
89
91
|
}
|
|
90
92
|
},
|
|
91
93
|
},
|