@ultimat3/core 25.0.0 → 25.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/README.md +1 -0
- package/package.json +2 -2
- package/src/actor.ts +12 -0
- package/src/index.ts +1 -0
- package/src/pg-executor.ts +2 -2
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ Zero dependencies, zero `@ultimat3/*` imports.
|
|
|
11
11
|
| the one lazy `AsyncLocalStorage`, every ambient scope in the framework | `async-context.ts` |
|
|
12
12
|
| request context on that seam | `context.ts` |
|
|
13
13
|
| `Actor` (`user \| service \| agent \| anonymous`) | `actor.ts` |
|
|
14
|
+
| whether a permission grant reaches a name — `grantCovers`, `*` and `<prefix>:*` | `actor.ts` |
|
|
14
15
|
| acting as another actor, with an origin and a reason | `impersonate.ts` |
|
|
15
16
|
| is an error worth retrying? one classification per code | `error-retry.ts` |
|
|
16
17
|
| how long to wait before the next attempt — one curve, one jitter table | `backoff.ts` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/core",
|
|
3
|
-
"version": "25.
|
|
3
|
+
"version": "25.1.0",
|
|
4
4
|
"description": "Ultimate's foundation: errors, context, env, config, clock, ids, logging, telemetry, lifecycle",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,6 @@
|
|
|
37
37
|
"test": "bun test"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ultimat3/schema": "25.
|
|
40
|
+
"@ultimat3/schema": "25.1.0"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/actor.ts
CHANGED
|
@@ -202,6 +202,18 @@ export function hasScope(actor: Actor, scope: string): boolean {
|
|
|
202
202
|
return actor.scopes.includes(scope);
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Whether one permission grant reaches `wanted`: `*` reaches everything, `<prefix>:*` every name
|
|
207
|
+
* beginning `<prefix>:` (any depth), anything else only itself. The PREFIX, never the first
|
|
208
|
+
* segment: `billing:invoice:*` read as "all of `billing`" granted refunds to an invoice clerk.
|
|
209
|
+
* Here, at tier 0, because `@ultimat3/policy` (`can()`) and `@ultimat3/auth` (an API key's cut
|
|
210
|
+
* to its owner) are one tier and may not share a copy — two copies were how it drifted.
|
|
211
|
+
*/
|
|
212
|
+
export function grantCovers(grant: string, wanted: string): boolean {
|
|
213
|
+
if (grant === '*' || grant === wanted) return true;
|
|
214
|
+
return grant.endsWith(':*') && wanted.startsWith(grant.slice(0, -1));
|
|
215
|
+
}
|
|
216
|
+
|
|
205
217
|
/**
|
|
206
218
|
* Attach resolved facts to an actor, once, at the request boundary — the one place that already
|
|
207
219
|
* awaited the database. Returns a new frozen actor, so the actor a predicate reads later cannot
|
package/src/index.ts
CHANGED
package/src/pg-executor.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* One method, positional parameters. **`Bun.sql` does not satisfy it** — `Bun.sql.query` is
|
|
7
7
|
* `undefined`; it is a tagged template whose positional form is `unsafe`, so `{ executor: Bun.sql }`
|
|
8
8
|
* would `TypeError` on the first statement. What satisfies it is a client that already speaks
|
|
9
|
-
* `(text, values)
|
|
10
|
-
*
|
|
9
|
+
* `(text, values)` — `@ultimat3/db`'s `dbExecutor()` over `DbClient.query({ text, values })` is
|
|
10
|
+
* the framework's own, and its one builder — or a transaction
|
|
11
11
|
* handle, which is a client on its own connection. It answers rows, never a command tag.
|
|
12
12
|
*/
|
|
13
13
|
export interface PgExecutor {
|