@objectstack/core 16.0.0 → 17.0.0-rc.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/dist/index.cjs +301 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +154 -4
- package/dist/index.d.ts +154 -4
- package/dist/index.js +296 -30
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -1751,6 +1751,14 @@ interface ResolvedAuthzContext {
|
|
|
1751
1751
|
tabPermissions?: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'>;
|
|
1752
1752
|
/** Fellow-org user IDs for RLS scoping of identity tables (`id IN (...)`). */
|
|
1753
1753
|
org_user_ids: string[];
|
|
1754
|
+
/**
|
|
1755
|
+
* [ADR-0105 D2] Every organization this principal currently holds a VALID
|
|
1756
|
+
* membership in — the caller's org access set, and the read reach of the
|
|
1757
|
+
* `group` tenancy posture (Layer 0 becomes `organization_id IN (...)`).
|
|
1758
|
+
* Resolved here, once, so no surface re-derives it; empty for an anonymous or
|
|
1759
|
+
* membership-less principal, which fails the group wall closed.
|
|
1760
|
+
*/
|
|
1761
|
+
accessible_org_ids: string[];
|
|
1754
1762
|
/**
|
|
1755
1763
|
* [ADR-0095 D2/D3] The monotonic posture rung this principal resolves to,
|
|
1756
1764
|
* DERIVED once here from held capability grants (never a better-auth role):
|
|
@@ -1781,6 +1789,58 @@ interface ResolveAuthzInput {
|
|
|
1781
1789
|
* never throws. Anonymous requests yield `{ positions: [], permissions: [], ... }`.
|
|
1782
1790
|
*/
|
|
1783
1791
|
declare function resolveAuthzContext(input: ResolveAuthzInput): Promise<ResolvedAuthzContext>;
|
|
1792
|
+
/** The authorization grants a KNOWN user holds — a subset of {@link ResolvedAuthzContext}. */
|
|
1793
|
+
interface UserAuthzGrants {
|
|
1794
|
+
positions: string[];
|
|
1795
|
+
permissions: string[];
|
|
1796
|
+
systemPermissions: string[];
|
|
1797
|
+
/** Fellow-org user IDs for RLS scoping of identity tables (`id IN (...)`). */
|
|
1798
|
+
org_user_ids: string[];
|
|
1799
|
+
/** [ADR-0105 D2] Organizations this user holds a currently-valid membership in. */
|
|
1800
|
+
accessible_org_ids: string[];
|
|
1801
|
+
tabPermissions?: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'>;
|
|
1802
|
+
posture?: AuthzPosture;
|
|
1803
|
+
/** The user's unique email (`sys_user`), for `current_user.email` owner RLS. */
|
|
1804
|
+
email?: string;
|
|
1805
|
+
}
|
|
1806
|
+
interface ResolveUserAuthzGrantsOptions {
|
|
1807
|
+
/** Active org/tenant id — scopes org-bound grants (a null-org row is global). */
|
|
1808
|
+
tenantId?: string;
|
|
1809
|
+
/** Clock injection for grant validity windows (tests). */
|
|
1810
|
+
nowMs?: number;
|
|
1811
|
+
/**
|
|
1812
|
+
* Permission names the CALLER already resolved (e.g. API-key scopes) to seed
|
|
1813
|
+
* `permissions` BEFORE permission-set names are appended, so a mixed
|
|
1814
|
+
* API-key+session principal keeps every scope and the ordering is preserved.
|
|
1815
|
+
* Copied, never mutated.
|
|
1816
|
+
*/
|
|
1817
|
+
seedPermissions?: string[];
|
|
1818
|
+
/** A caller-supplied email (e.g. from the session) that wins over the `sys_user` read. */
|
|
1819
|
+
seedEmail?: string;
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* resolveUserAuthzGrants — the userId-driven core of {@link resolveAuthzContext}.
|
|
1823
|
+
*
|
|
1824
|
+
* Given a KNOWN user id, aggregate the authorization grants that user holds:
|
|
1825
|
+
* org-admin positions (`sys_member`), platform-RBAC positions
|
|
1826
|
+
* (`sys_user_position`), user- and position-bound permission sets
|
|
1827
|
+
* (`sys_user_permission_set` / `sys_position_permission_set` →
|
|
1828
|
+
* `sys_permission_set`), the derived `platform_admin` built-in + posture rung,
|
|
1829
|
+
* fellow-org peers for identity-table RLS, and the env-side `ai_seat`.
|
|
1830
|
+
*
|
|
1831
|
+
* Factored out of `resolveAuthzContext` so a surface that already knows WHO the
|
|
1832
|
+
* principal is — with no HTTP request to resolve it from — can build the SAME
|
|
1833
|
+
* envelope through the ONE resolver, instead of re-reading `sys_member` /
|
|
1834
|
+
* `sys_user_position` / `sys_*_permission_set` itself. The motivating consumer
|
|
1835
|
+
* is a `runAs:'user'` automation run resolving the triggering user's grants
|
|
1836
|
+
* (#3356): the record-change hook session carries only a `userId`, so the
|
|
1837
|
+
* automation engine calls this to run the flow's data ops exactly as that user
|
|
1838
|
+
* — not the bare member/everyone fallback the missing grants used to leave it.
|
|
1839
|
+
*
|
|
1840
|
+
* Fail-closed like its parent: every read is defensive, a missing engine/table
|
|
1841
|
+
* yields an empty-but-valid envelope, and it never throws.
|
|
1842
|
+
*/
|
|
1843
|
+
declare function resolveUserAuthzGrants(ql: any, userId: string, opts?: ResolveUserAuthzGrantsOptions): Promise<UserAuthzGrants>;
|
|
1784
1844
|
interface ResolveLocalizationInput {
|
|
1785
1845
|
ql: any;
|
|
1786
1846
|
/** Settings service exposing `get(namespace, key, { tenantId, userId })`. */
|
|
@@ -2073,12 +2133,16 @@ type BucketGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year';
|
|
|
2073
2133
|
* `datetime` field in a reference timezone layers that on top (and, per
|
|
2074
2134
|
* ADR-0053, a `date` field compares against these `YYYY-MM-DD` bounds directly).
|
|
2075
2135
|
*
|
|
2076
|
-
* Returns `null` for the
|
|
2077
|
-
*
|
|
2136
|
+
* Returns `null` for the empty bucket, an unparseable key, or a key that is
|
|
2137
|
+
* shape-valid but out of range (e.g. `2026-13`, a `-W53` in a 52-week year,
|
|
2078
2138
|
* `2026-02-30`). Callers drop the range and fall back to an unscoped (superset)
|
|
2079
2139
|
* drill rather than emit a wrong bound.
|
|
2140
|
+
*
|
|
2141
|
+
* `key` admits `null` because that IS the empty bucket's key on both aggregation
|
|
2142
|
+
* paths (#3839); callers pass a grouped row's dimension value straight through
|
|
2143
|
+
* rather than casting a lie.
|
|
2080
2144
|
*/
|
|
2081
|
-
declare function bucketKeyToCalendarRange(key: string, granularity: BucketGranularity): {
|
|
2145
|
+
declare function bucketKeyToCalendarRange(key: string | null | undefined, granularity: BucketGranularity): {
|
|
2082
2146
|
start: string;
|
|
2083
2147
|
end: string;
|
|
2084
2148
|
} | null;
|
|
@@ -2201,6 +2265,92 @@ declare function withTransientRetry<T>(fn: (attempt: number) => Promise<T>, opts
|
|
|
2201
2265
|
*/
|
|
2202
2266
|
declare function bulkWrite<TRow, TRecord = any>(rows: TRow[], opts: BulkWriteOptions<TRow, TRecord>): Promise<BulkWriteRowResult<TRecord>[]>;
|
|
2203
2267
|
|
|
2268
|
+
/**
|
|
2269
|
+
* The slice of an execution context the resolver reads. Structural on purpose —
|
|
2270
|
+
* see {@link filterTokenContextFrom}.
|
|
2271
|
+
*/
|
|
2272
|
+
interface ExecutionContextLike {
|
|
2273
|
+
readonly userId?: string;
|
|
2274
|
+
readonly tenantId?: string;
|
|
2275
|
+
readonly timezone?: string;
|
|
2276
|
+
}
|
|
2277
|
+
/**
|
|
2278
|
+
* The request-scoped values a placeholder can resolve against.
|
|
2279
|
+
*
|
|
2280
|
+
* `now` is captured ONCE per resolve call so every token in one filter shares
|
|
2281
|
+
* an instant — otherwise a `$gte {current_month_start}` / `$lt
|
|
2282
|
+
* {next_month_start}` pair evaluated microseconds apart could straddle a
|
|
2283
|
+
* month boundary and silently drop a row.
|
|
2284
|
+
*/
|
|
2285
|
+
interface FilterTokenResolutionContext {
|
|
2286
|
+
/** Reference instant. Defaults to `new Date()` at call time. */
|
|
2287
|
+
now?: Date;
|
|
2288
|
+
/** IANA reference timezone for calendar boundaries. Defaults to UTC. */
|
|
2289
|
+
timezone?: string;
|
|
2290
|
+
/** Resolves `{current_user_id}`. */
|
|
2291
|
+
userId?: string;
|
|
2292
|
+
/** Resolves `{current_org_id}`. */
|
|
2293
|
+
orgId?: string;
|
|
2294
|
+
}
|
|
2295
|
+
/**
|
|
2296
|
+
* Raised when a filter carries a placeholder outside the vocabulary.
|
|
2297
|
+
*
|
|
2298
|
+
* Carries `status`/`code` so the REST layer's generic 4xx passthrough maps it
|
|
2299
|
+
* to a **400 with a fixable message** rather than a 500: the caller's filter is
|
|
2300
|
+
* malformed, the server is fine. (Same convention plugin-sharing uses for its
|
|
2301
|
+
* record-scope denial — no runtime dependency in either direction.)
|
|
2302
|
+
*/
|
|
2303
|
+
declare class UnknownFilterTokenError extends Error {
|
|
2304
|
+
readonly token: string;
|
|
2305
|
+
readonly suggestion?: string;
|
|
2306
|
+
readonly status = 400;
|
|
2307
|
+
readonly code = "FILTER_TOKEN_UNKNOWN";
|
|
2308
|
+
constructor(token: string, suggestion?: string);
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Raised when a token IS in the vocabulary but the request carries no value
|
|
2312
|
+
* for it — an unauthenticated caller filtering on `{current_user_id}`.
|
|
2313
|
+
*
|
|
2314
|
+
* Distinct from {@link UnknownFilterTokenError} because the fix is different:
|
|
2315
|
+
* the metadata is correct, the context is not. Never silently resolves to
|
|
2316
|
+
* `null`/`undefined`, which on most drivers degrades to `IS NULL` and would
|
|
2317
|
+
* quietly hand back rows the filter was written to exclude.
|
|
2318
|
+
*/
|
|
2319
|
+
declare class UnresolvedFilterTokenError extends Error {
|
|
2320
|
+
readonly token: string;
|
|
2321
|
+
/** 400, not 500 — see {@link UnknownFilterTokenError}. */
|
|
2322
|
+
readonly status = 400;
|
|
2323
|
+
readonly code = "FILTER_TOKEN_UNRESOLVED";
|
|
2324
|
+
constructor(token: string, detail: string);
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Resolve one token NAME (the bit inside the braces) to its concrete value.
|
|
2328
|
+
* Throws {@link UnresolvedFilterTokenError} for a vocabulary token the request
|
|
2329
|
+
* carries no value for. Returns `undefined` only when the token is outside the
|
|
2330
|
+
* vocabulary — callers turn that into {@link UnknownFilterTokenError}.
|
|
2331
|
+
*/
|
|
2332
|
+
declare function resolveFilterToken(token: string, ctx?: FilterTokenResolutionContext): unknown;
|
|
2333
|
+
/**
|
|
2334
|
+
* Deep-replace every fully-wrapped placeholder in `filter` with its resolved
|
|
2335
|
+
* value, returning a NEW tree (the caller's metadata is never mutated — a view
|
|
2336
|
+
* or dataset definition is shared across requests, so resolving in place would
|
|
2337
|
+
* bake one request's user id, and one day's dates, into every later render).
|
|
2338
|
+
*
|
|
2339
|
+
* Returns the input unchanged, by reference, when it holds no placeholders.
|
|
2340
|
+
*/
|
|
2341
|
+
declare function resolveFilterTokens<T>(filter: T, ctx?: FilterTokenResolutionContext): T;
|
|
2342
|
+
/**
|
|
2343
|
+
* Convenience bridge from an execution context to the resolver's inputs.
|
|
2344
|
+
* `{current_org_id}` reads `tenantId` — the active organization IS the tenant
|
|
2345
|
+
* on the read path (same value the RLS compiler binds to
|
|
2346
|
+
* `current_user.organization_id`).
|
|
2347
|
+
*
|
|
2348
|
+
* Typed structurally, not as `ExecutionContext`, so both the parsed context
|
|
2349
|
+
* (defaults applied) and the pre-parse `ExecutionContextInput` a caller holds
|
|
2350
|
+
* mid-pipeline satisfy it. The three fields read here are optional in both.
|
|
2351
|
+
*/
|
|
2352
|
+
declare function filterTokenContextFrom(execCtx: ExecutionContextLike | undefined, now?: Date): FilterTokenResolutionContext;
|
|
2353
|
+
|
|
2204
2354
|
/**
|
|
2205
2355
|
* In-memory Map-backed cache fallback.
|
|
2206
2356
|
*
|
|
@@ -2637,4 +2787,4 @@ declare class NamespaceResolver {
|
|
|
2637
2787
|
private suggestAlternative;
|
|
2638
2788
|
}
|
|
2639
2789
|
|
|
2640
|
-
export { ANONYMOUS_DENY_BODY, ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_MESSAGE, ANONYMOUS_DENY_STATUS, API_KEY_PREFIX, type AnonymousDenyInput, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BucketGranularity, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, type LadderPrincipal, type LadderRow, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, POSTURE_INJECTION_RULE, POSTURE_LADDER, POSTURE_RANK, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PostureEvidence, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, type VersionCompatibility, bucketKeyToCalendarRange, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, derivePosture, evaluateAuthGate, extractApiKey, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, postureVisibleRows, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveLocale, resolveLocalizationContext, safeExit, shouldDenyAnonymous, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry, zonedDateStartToUtcMs };
|
|
2790
|
+
export { ANONYMOUS_DENY_BODY, ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_MESSAGE, ANONYMOUS_DENY_STATUS, API_KEY_PREFIX, type AnonymousDenyInput, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BucketGranularity, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type ExecutionContextLike, type FilterTokenResolutionContext, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, type LadderPrincipal, type LadderRow, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, POSTURE_INJECTION_RULE, POSTURE_LADDER, POSTURE_RANK, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PostureEvidence, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolveUserAuthzGrantsOptions, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, UnknownFilterTokenError, UnresolvedFilterTokenError, type UserAuthzGrants, type VersionCompatibility, bucketKeyToCalendarRange, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, derivePosture, evaluateAuthGate, extractApiKey, filterTokenContextFrom, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, postureVisibleRows, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveFilterToken, resolveFilterTokens, resolveLocale, resolveLocalizationContext, resolveUserAuthzGrants, safeExit, shouldDenyAnonymous, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry, zonedDateStartToUtcMs };
|
package/dist/index.d.ts
CHANGED
|
@@ -1751,6 +1751,14 @@ interface ResolvedAuthzContext {
|
|
|
1751
1751
|
tabPermissions?: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'>;
|
|
1752
1752
|
/** Fellow-org user IDs for RLS scoping of identity tables (`id IN (...)`). */
|
|
1753
1753
|
org_user_ids: string[];
|
|
1754
|
+
/**
|
|
1755
|
+
* [ADR-0105 D2] Every organization this principal currently holds a VALID
|
|
1756
|
+
* membership in — the caller's org access set, and the read reach of the
|
|
1757
|
+
* `group` tenancy posture (Layer 0 becomes `organization_id IN (...)`).
|
|
1758
|
+
* Resolved here, once, so no surface re-derives it; empty for an anonymous or
|
|
1759
|
+
* membership-less principal, which fails the group wall closed.
|
|
1760
|
+
*/
|
|
1761
|
+
accessible_org_ids: string[];
|
|
1754
1762
|
/**
|
|
1755
1763
|
* [ADR-0095 D2/D3] The monotonic posture rung this principal resolves to,
|
|
1756
1764
|
* DERIVED once here from held capability grants (never a better-auth role):
|
|
@@ -1781,6 +1789,58 @@ interface ResolveAuthzInput {
|
|
|
1781
1789
|
* never throws. Anonymous requests yield `{ positions: [], permissions: [], ... }`.
|
|
1782
1790
|
*/
|
|
1783
1791
|
declare function resolveAuthzContext(input: ResolveAuthzInput): Promise<ResolvedAuthzContext>;
|
|
1792
|
+
/** The authorization grants a KNOWN user holds — a subset of {@link ResolvedAuthzContext}. */
|
|
1793
|
+
interface UserAuthzGrants {
|
|
1794
|
+
positions: string[];
|
|
1795
|
+
permissions: string[];
|
|
1796
|
+
systemPermissions: string[];
|
|
1797
|
+
/** Fellow-org user IDs for RLS scoping of identity tables (`id IN (...)`). */
|
|
1798
|
+
org_user_ids: string[];
|
|
1799
|
+
/** [ADR-0105 D2] Organizations this user holds a currently-valid membership in. */
|
|
1800
|
+
accessible_org_ids: string[];
|
|
1801
|
+
tabPermissions?: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'>;
|
|
1802
|
+
posture?: AuthzPosture;
|
|
1803
|
+
/** The user's unique email (`sys_user`), for `current_user.email` owner RLS. */
|
|
1804
|
+
email?: string;
|
|
1805
|
+
}
|
|
1806
|
+
interface ResolveUserAuthzGrantsOptions {
|
|
1807
|
+
/** Active org/tenant id — scopes org-bound grants (a null-org row is global). */
|
|
1808
|
+
tenantId?: string;
|
|
1809
|
+
/** Clock injection for grant validity windows (tests). */
|
|
1810
|
+
nowMs?: number;
|
|
1811
|
+
/**
|
|
1812
|
+
* Permission names the CALLER already resolved (e.g. API-key scopes) to seed
|
|
1813
|
+
* `permissions` BEFORE permission-set names are appended, so a mixed
|
|
1814
|
+
* API-key+session principal keeps every scope and the ordering is preserved.
|
|
1815
|
+
* Copied, never mutated.
|
|
1816
|
+
*/
|
|
1817
|
+
seedPermissions?: string[];
|
|
1818
|
+
/** A caller-supplied email (e.g. from the session) that wins over the `sys_user` read. */
|
|
1819
|
+
seedEmail?: string;
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* resolveUserAuthzGrants — the userId-driven core of {@link resolveAuthzContext}.
|
|
1823
|
+
*
|
|
1824
|
+
* Given a KNOWN user id, aggregate the authorization grants that user holds:
|
|
1825
|
+
* org-admin positions (`sys_member`), platform-RBAC positions
|
|
1826
|
+
* (`sys_user_position`), user- and position-bound permission sets
|
|
1827
|
+
* (`sys_user_permission_set` / `sys_position_permission_set` →
|
|
1828
|
+
* `sys_permission_set`), the derived `platform_admin` built-in + posture rung,
|
|
1829
|
+
* fellow-org peers for identity-table RLS, and the env-side `ai_seat`.
|
|
1830
|
+
*
|
|
1831
|
+
* Factored out of `resolveAuthzContext` so a surface that already knows WHO the
|
|
1832
|
+
* principal is — with no HTTP request to resolve it from — can build the SAME
|
|
1833
|
+
* envelope through the ONE resolver, instead of re-reading `sys_member` /
|
|
1834
|
+
* `sys_user_position` / `sys_*_permission_set` itself. The motivating consumer
|
|
1835
|
+
* is a `runAs:'user'` automation run resolving the triggering user's grants
|
|
1836
|
+
* (#3356): the record-change hook session carries only a `userId`, so the
|
|
1837
|
+
* automation engine calls this to run the flow's data ops exactly as that user
|
|
1838
|
+
* — not the bare member/everyone fallback the missing grants used to leave it.
|
|
1839
|
+
*
|
|
1840
|
+
* Fail-closed like its parent: every read is defensive, a missing engine/table
|
|
1841
|
+
* yields an empty-but-valid envelope, and it never throws.
|
|
1842
|
+
*/
|
|
1843
|
+
declare function resolveUserAuthzGrants(ql: any, userId: string, opts?: ResolveUserAuthzGrantsOptions): Promise<UserAuthzGrants>;
|
|
1784
1844
|
interface ResolveLocalizationInput {
|
|
1785
1845
|
ql: any;
|
|
1786
1846
|
/** Settings service exposing `get(namespace, key, { tenantId, userId })`. */
|
|
@@ -2073,12 +2133,16 @@ type BucketGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year';
|
|
|
2073
2133
|
* `datetime` field in a reference timezone layers that on top (and, per
|
|
2074
2134
|
* ADR-0053, a `date` field compares against these `YYYY-MM-DD` bounds directly).
|
|
2075
2135
|
*
|
|
2076
|
-
* Returns `null` for the
|
|
2077
|
-
*
|
|
2136
|
+
* Returns `null` for the empty bucket, an unparseable key, or a key that is
|
|
2137
|
+
* shape-valid but out of range (e.g. `2026-13`, a `-W53` in a 52-week year,
|
|
2078
2138
|
* `2026-02-30`). Callers drop the range and fall back to an unscoped (superset)
|
|
2079
2139
|
* drill rather than emit a wrong bound.
|
|
2140
|
+
*
|
|
2141
|
+
* `key` admits `null` because that IS the empty bucket's key on both aggregation
|
|
2142
|
+
* paths (#3839); callers pass a grouped row's dimension value straight through
|
|
2143
|
+
* rather than casting a lie.
|
|
2080
2144
|
*/
|
|
2081
|
-
declare function bucketKeyToCalendarRange(key: string, granularity: BucketGranularity): {
|
|
2145
|
+
declare function bucketKeyToCalendarRange(key: string | null | undefined, granularity: BucketGranularity): {
|
|
2082
2146
|
start: string;
|
|
2083
2147
|
end: string;
|
|
2084
2148
|
} | null;
|
|
@@ -2201,6 +2265,92 @@ declare function withTransientRetry<T>(fn: (attempt: number) => Promise<T>, opts
|
|
|
2201
2265
|
*/
|
|
2202
2266
|
declare function bulkWrite<TRow, TRecord = any>(rows: TRow[], opts: BulkWriteOptions<TRow, TRecord>): Promise<BulkWriteRowResult<TRecord>[]>;
|
|
2203
2267
|
|
|
2268
|
+
/**
|
|
2269
|
+
* The slice of an execution context the resolver reads. Structural on purpose —
|
|
2270
|
+
* see {@link filterTokenContextFrom}.
|
|
2271
|
+
*/
|
|
2272
|
+
interface ExecutionContextLike {
|
|
2273
|
+
readonly userId?: string;
|
|
2274
|
+
readonly tenantId?: string;
|
|
2275
|
+
readonly timezone?: string;
|
|
2276
|
+
}
|
|
2277
|
+
/**
|
|
2278
|
+
* The request-scoped values a placeholder can resolve against.
|
|
2279
|
+
*
|
|
2280
|
+
* `now` is captured ONCE per resolve call so every token in one filter shares
|
|
2281
|
+
* an instant — otherwise a `$gte {current_month_start}` / `$lt
|
|
2282
|
+
* {next_month_start}` pair evaluated microseconds apart could straddle a
|
|
2283
|
+
* month boundary and silently drop a row.
|
|
2284
|
+
*/
|
|
2285
|
+
interface FilterTokenResolutionContext {
|
|
2286
|
+
/** Reference instant. Defaults to `new Date()` at call time. */
|
|
2287
|
+
now?: Date;
|
|
2288
|
+
/** IANA reference timezone for calendar boundaries. Defaults to UTC. */
|
|
2289
|
+
timezone?: string;
|
|
2290
|
+
/** Resolves `{current_user_id}`. */
|
|
2291
|
+
userId?: string;
|
|
2292
|
+
/** Resolves `{current_org_id}`. */
|
|
2293
|
+
orgId?: string;
|
|
2294
|
+
}
|
|
2295
|
+
/**
|
|
2296
|
+
* Raised when a filter carries a placeholder outside the vocabulary.
|
|
2297
|
+
*
|
|
2298
|
+
* Carries `status`/`code` so the REST layer's generic 4xx passthrough maps it
|
|
2299
|
+
* to a **400 with a fixable message** rather than a 500: the caller's filter is
|
|
2300
|
+
* malformed, the server is fine. (Same convention plugin-sharing uses for its
|
|
2301
|
+
* record-scope denial — no runtime dependency in either direction.)
|
|
2302
|
+
*/
|
|
2303
|
+
declare class UnknownFilterTokenError extends Error {
|
|
2304
|
+
readonly token: string;
|
|
2305
|
+
readonly suggestion?: string;
|
|
2306
|
+
readonly status = 400;
|
|
2307
|
+
readonly code = "FILTER_TOKEN_UNKNOWN";
|
|
2308
|
+
constructor(token: string, suggestion?: string);
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Raised when a token IS in the vocabulary but the request carries no value
|
|
2312
|
+
* for it — an unauthenticated caller filtering on `{current_user_id}`.
|
|
2313
|
+
*
|
|
2314
|
+
* Distinct from {@link UnknownFilterTokenError} because the fix is different:
|
|
2315
|
+
* the metadata is correct, the context is not. Never silently resolves to
|
|
2316
|
+
* `null`/`undefined`, which on most drivers degrades to `IS NULL` and would
|
|
2317
|
+
* quietly hand back rows the filter was written to exclude.
|
|
2318
|
+
*/
|
|
2319
|
+
declare class UnresolvedFilterTokenError extends Error {
|
|
2320
|
+
readonly token: string;
|
|
2321
|
+
/** 400, not 500 — see {@link UnknownFilterTokenError}. */
|
|
2322
|
+
readonly status = 400;
|
|
2323
|
+
readonly code = "FILTER_TOKEN_UNRESOLVED";
|
|
2324
|
+
constructor(token: string, detail: string);
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Resolve one token NAME (the bit inside the braces) to its concrete value.
|
|
2328
|
+
* Throws {@link UnresolvedFilterTokenError} for a vocabulary token the request
|
|
2329
|
+
* carries no value for. Returns `undefined` only when the token is outside the
|
|
2330
|
+
* vocabulary — callers turn that into {@link UnknownFilterTokenError}.
|
|
2331
|
+
*/
|
|
2332
|
+
declare function resolveFilterToken(token: string, ctx?: FilterTokenResolutionContext): unknown;
|
|
2333
|
+
/**
|
|
2334
|
+
* Deep-replace every fully-wrapped placeholder in `filter` with its resolved
|
|
2335
|
+
* value, returning a NEW tree (the caller's metadata is never mutated — a view
|
|
2336
|
+
* or dataset definition is shared across requests, so resolving in place would
|
|
2337
|
+
* bake one request's user id, and one day's dates, into every later render).
|
|
2338
|
+
*
|
|
2339
|
+
* Returns the input unchanged, by reference, when it holds no placeholders.
|
|
2340
|
+
*/
|
|
2341
|
+
declare function resolveFilterTokens<T>(filter: T, ctx?: FilterTokenResolutionContext): T;
|
|
2342
|
+
/**
|
|
2343
|
+
* Convenience bridge from an execution context to the resolver's inputs.
|
|
2344
|
+
* `{current_org_id}` reads `tenantId` — the active organization IS the tenant
|
|
2345
|
+
* on the read path (same value the RLS compiler binds to
|
|
2346
|
+
* `current_user.organization_id`).
|
|
2347
|
+
*
|
|
2348
|
+
* Typed structurally, not as `ExecutionContext`, so both the parsed context
|
|
2349
|
+
* (defaults applied) and the pre-parse `ExecutionContextInput` a caller holds
|
|
2350
|
+
* mid-pipeline satisfy it. The three fields read here are optional in both.
|
|
2351
|
+
*/
|
|
2352
|
+
declare function filterTokenContextFrom(execCtx: ExecutionContextLike | undefined, now?: Date): FilterTokenResolutionContext;
|
|
2353
|
+
|
|
2204
2354
|
/**
|
|
2205
2355
|
* In-memory Map-backed cache fallback.
|
|
2206
2356
|
*
|
|
@@ -2637,4 +2787,4 @@ declare class NamespaceResolver {
|
|
|
2637
2787
|
private suggestAlternative;
|
|
2638
2788
|
}
|
|
2639
2789
|
|
|
2640
|
-
export { ANONYMOUS_DENY_BODY, ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_MESSAGE, ANONYMOUS_DENY_STATUS, API_KEY_PREFIX, type AnonymousDenyInput, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BucketGranularity, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, type LadderPrincipal, type LadderRow, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, POSTURE_INJECTION_RULE, POSTURE_LADDER, POSTURE_RANK, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PostureEvidence, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, type VersionCompatibility, bucketKeyToCalendarRange, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, derivePosture, evaluateAuthGate, extractApiKey, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, postureVisibleRows, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveLocale, resolveLocalizationContext, safeExit, shouldDenyAnonymous, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry, zonedDateStartToUtcMs };
|
|
2790
|
+
export { ANONYMOUS_DENY_BODY, ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_MESSAGE, ANONYMOUS_DENY_STATUS, API_KEY_PREFIX, type AnonymousDenyInput, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BucketGranularity, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type ExecutionContextLike, type FilterTokenResolutionContext, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, type LadderPrincipal, type LadderRow, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, POSTURE_INJECTION_RULE, POSTURE_LADDER, POSTURE_RANK, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PostureEvidence, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolveUserAuthzGrantsOptions, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, UnknownFilterTokenError, UnresolvedFilterTokenError, type UserAuthzGrants, type VersionCompatibility, bucketKeyToCalendarRange, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, derivePosture, evaluateAuthGate, extractApiKey, filterTokenContextFrom, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, postureVisibleRows, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveFilterToken, resolveFilterTokens, resolveLocale, resolveLocalizationContext, resolveUserAuthzGrants, safeExit, shouldDenyAnonymous, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry, zonedDateStartToUtcMs };
|