@cosmicdrift/kumiko-types 0.327.0 → 0.328.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/dist/action-icon.d.ts +3 -0
- package/dist/action-icon.js +51 -0
- package/{src/agent-exposure.ts → dist/agent-exposure.d.ts} +8 -15
- package/dist/agent-exposure.js +16 -0
- package/dist/concurrency-mode.d.ts +1 -0
- package/dist/config-scope.d.ts +1 -0
- package/dist/config-scope.js +1 -0
- package/dist/config.d.ts +234 -0
- package/dist/config.js +1 -0
- package/dist/cursor-types.d.ts +16 -0
- package/dist/cursor-types.js +1 -0
- package/dist/db-connection.d.ts +14 -0
- package/dist/db-connection.js +1 -0
- package/dist/define-handler.d.ts +58 -0
- package/dist/define-handler.js +1 -0
- package/dist/derivatives-types.d.ts +53 -0
- package/dist/derivatives-types.js +3 -0
- package/dist/entity-cache.d.ts +16 -0
- package/dist/entity-cache.js +1 -0
- package/dist/entity-handlers.d.ts +54 -0
- package/dist/entity-handlers.js +1 -0
- package/dist/entity-table-meta-types.d.ts +44 -0
- package/dist/entity-table-meta-types.js +6 -0
- package/dist/envelope-cipher-types.d.ts +5 -0
- package/dist/envelope-cipher-types.js +1 -0
- package/dist/event-store-executor-types.d.ts +86 -0
- package/dist/event-store-executor-types.js +1 -0
- package/dist/event-store-types.d.ts +37 -0
- package/dist/event-store-types.js +7 -0
- package/dist/event-type-map.d.ts +8 -0
- package/{src/event-type-map.ts → dist/event-type-map.js} +1 -16
- package/dist/executor-brand.d.ts +8 -0
- package/dist/executor-brand.js +1 -0
- package/dist/extension-options-map.d.ts +9 -0
- package/dist/extension-options-map.js +4 -0
- package/dist/feature.d.ts +518 -0
- package/dist/feature.js +1 -0
- package/dist/field-icon.d.ts +1 -0
- package/dist/field-icon.js +1 -0
- package/dist/fields.d.ts +729 -0
- package/dist/fields.js +50 -0
- package/dist/file-handle-types.d.ts +12 -0
- package/dist/file-handle-types.js +1 -0
- package/dist/file-provider-resolver-types.d.ts +3 -0
- package/dist/file-provider-resolver-types.js +1 -0
- package/dist/file-storage-provider-types.d.ts +17 -0
- package/dist/file-storage-provider-types.js +1 -0
- package/dist/geo-tz.d.ts +17 -0
- package/{src/geo-tz.ts → dist/geo-tz.js} +1 -20
- package/dist/handlers.d.ts +493 -0
- package/dist/handlers.js +49 -0
- package/dist/hook-phase.d.ts +1 -0
- package/dist/hook-phase.js +1 -0
- package/dist/hooks.d.ts +75 -0
- package/dist/hooks.js +1 -0
- package/dist/http-route.d.ts +52 -0
- package/dist/http-route.js +13 -0
- package/dist/identifiers.d.ts +8 -0
- package/{src/identifiers.ts → dist/identifiers.js} +7 -24
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/kms-adapter-types.d.ts +68 -0
- package/dist/kms-adapter-types.js +49 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +1 -0
- package/dist/multi-stream-apply-context-types.d.ts +18 -0
- package/dist/multi-stream-apply-context-types.js +1 -0
- package/dist/nav-icon.d.ts +3 -0
- package/dist/nav-icon.js +100 -0
- package/dist/nav.d.ts +39 -0
- package/dist/nav.js +1 -0
- package/dist/observability/index.d.ts +3 -0
- package/dist/observability/index.js +2 -0
- package/dist/observability/metric.d.ts +34 -0
- package/dist/observability/metric.js +3 -0
- package/dist/observability/provider.d.ts +24 -0
- package/dist/observability/provider.js +4 -0
- package/dist/observability/span.d.ts +32 -0
- package/dist/observability/span.js +4 -0
- package/dist/ownership.d.ts +33 -0
- package/dist/ownership.js +5 -0
- package/dist/projection.d.ts +38 -0
- package/dist/projection.js +1 -0
- package/dist/rate-limit-types.d.ts +19 -0
- package/dist/rate-limit-types.js +1 -0
- package/dist/relations.d.ts +25 -0
- package/dist/relations.js +1 -0
- package/dist/schema-table-types.d.ts +15 -0
- package/{src/schema-table-types.ts → dist/schema-table-types.js} +0 -20
- package/dist/screen.d.ts +1265 -0
- package/dist/screen.js +3 -0
- package/dist/search-adapter.d.ts +32 -0
- package/dist/search-adapter.js +1 -0
- package/dist/secrets-types.d.ts +52 -0
- package/dist/secrets-types.js +30 -0
- package/dist/snapshot-types.d.ts +13 -0
- package/dist/snapshot-types.js +1 -0
- package/dist/step.d.ts +304 -0
- package/dist/step.js +11 -0
- package/dist/target-ref.d.ts +5 -0
- package/{src/target-ref.ts → dist/target-ref.js} +1 -6
- package/dist/tenancy-brand.d.ts +6 -0
- package/dist/tenancy-brand.js +1 -0
- package/dist/tenant-db-types.d.ts +67 -0
- package/dist/tenant-db-types.js +5 -0
- package/dist/tree-node.d.ts +26 -0
- package/dist/tree-node.js +22 -0
- package/dist/tz-context.d.ts +48 -0
- package/dist/tz-context.js +6 -0
- package/dist/websocket-route.d.ts +46 -0
- package/dist/websocket-route.js +10 -0
- package/dist/where-clause-types.d.ts +20 -0
- package/dist/where-clause-types.js +1 -0
- package/dist/workspace.d.ts +10 -0
- package/dist/workspace.js +1 -0
- package/dist/write-error-info-types.d.ts +12 -0
- package/dist/write-error-info-types.js +1 -0
- package/package.json +372 -124
- package/src/changes.json +18 -0
- package/src/__tests__/handlers.test.ts +0 -40
- package/src/__tests__/plural-forms.test.ts +0 -18
- package/src/action-icon.ts +0 -57
- package/src/concurrency-mode.ts +0 -5
- package/src/config-scope.ts +0 -5
- package/src/config.ts +0 -563
- package/src/cursor-types.ts +0 -18
- package/src/db-connection.ts +0 -25
- package/src/define-handler.ts +0 -138
- package/src/derivatives-types.ts +0 -106
- package/src/entity-cache.ts +0 -35
- package/src/entity-handlers.ts +0 -68
- package/src/entity-table-meta-types.ts +0 -101
- package/src/envelope-cipher-types.ts +0 -6
- package/src/event-store-executor-types.ts +0 -163
- package/src/event-store-types.ts +0 -85
- package/src/executor-brand.ts +0 -19
- package/src/extension-options-map.ts +0 -21
- package/src/feature.ts +0 -1141
- package/src/field-icon.ts +0 -23
- package/src/fields.ts +0 -1114
- package/src/file-handle-types.ts +0 -20
- package/src/file-provider-resolver-types.ts +0 -7
- package/src/file-storage-provider-types.ts +0 -54
- package/src/handlers.ts +0 -1246
- package/src/hook-phase.ts +0 -2
- package/src/hooks.ts +0 -170
- package/src/http-route.ts +0 -78
- package/src/kms-adapter-types.ts +0 -128
- package/src/logger.ts +0 -7
- package/src/multi-stream-apply-context-types.ts +0 -52
- package/src/nav-icon.ts +0 -105
- package/src/nav.ts +0 -139
- package/src/observability/index.ts +0 -28
- package/src/observability/metric.ts +0 -56
- package/src/observability/provider.ts +0 -32
- package/src/observability/span.ts +0 -58
- package/src/ownership.ts +0 -83
- package/src/projection.ts +0 -170
- package/src/rate-limit-types.ts +0 -32
- package/src/relations.ts +0 -52
- package/src/screen.ts +0 -1593
- package/src/search-adapter.ts +0 -45
- package/src/secrets-types.ts +0 -182
- package/src/snapshot-types.ts +0 -36
- package/src/step.ts +0 -390
- package/src/tenancy-brand.ts +0 -9
- package/src/tenant-db-types.ts +0 -116
- package/src/tree-node.ts +0 -134
- package/src/tz-context.ts +0 -63
- package/src/websocket-route.ts +0 -68
- package/src/where-clause-types.ts +0 -31
- package/src/workspace.ts +0 -42
- package/src/write-error-info-types.ts +0 -20
- /package/{src/index.ts → dist/concurrency-mode.js} +0 -0
package/dist/handlers.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// AccessRule can arrive from untyped sources (pattern-library JSON, Designer)
|
|
2
|
+
// where `openToAll` doesn't actually match the declared union — narrow via
|
|
3
|
+
// `unknown` instead of trusting the static type, deny on anything malformed.
|
|
4
|
+
export function isOpenToAllGranted(rule) {
|
|
5
|
+
if (!("openToAll" in rule))
|
|
6
|
+
return false;
|
|
7
|
+
const openToAll = rule.openToAll;
|
|
8
|
+
if (typeof openToAll !== "object" || openToAll === null)
|
|
9
|
+
return false;
|
|
10
|
+
if (!("reason" in openToAll) || typeof openToAll.reason !== "string")
|
|
11
|
+
return false;
|
|
12
|
+
return openToAll.reason.trim().length > 0;
|
|
13
|
+
}
|
|
14
|
+
// UI-visibility predicate — DEFAULT-VISIBLE, the opposite stance from
|
|
15
|
+
// `hasAccess`/AccessRule's own default-deny doc above: an unset `access`
|
|
16
|
+
// means every signed-in user may see the screen/nav/workspace, not nobody.
|
|
17
|
+
// The engine's dispatcher access check stays default-deny; this only
|
|
18
|
+
// decides what a client renders/lists, never what a handler accepts.
|
|
19
|
+
// Same `unknown`-narrowing caution as isOpenToAllGranted — `access` can
|
|
20
|
+
// arrive from untyped sources.
|
|
21
|
+
export function isUiAccessGranted(access, userRoles) {
|
|
22
|
+
if (access === undefined)
|
|
23
|
+
return true;
|
|
24
|
+
if ("openToAll" in access)
|
|
25
|
+
return isOpenToAllGranted(access);
|
|
26
|
+
if (userRoles === undefined)
|
|
27
|
+
return false;
|
|
28
|
+
if (!("roles" in access))
|
|
29
|
+
return false;
|
|
30
|
+
return access.roles.some((role) => userRoles.includes(role));
|
|
31
|
+
}
|
|
32
|
+
export function normalizeEventPiiSubject(spec) {
|
|
33
|
+
if ("subjectField" in spec) {
|
|
34
|
+
return { kind: "user", ownerField: spec.subjectField, whenAbsent: undefined };
|
|
35
|
+
}
|
|
36
|
+
if (spec.personal === "tenant")
|
|
37
|
+
return { kind: "tenant" };
|
|
38
|
+
if (spec.personal === "self")
|
|
39
|
+
return { kind: "self" };
|
|
40
|
+
return { kind: "user", ownerField: spec.personal.of, whenAbsent: spec.personal.whenAbsent };
|
|
41
|
+
}
|
|
42
|
+
export function isRateLimitDisabled(v) {
|
|
43
|
+
return v !== undefined && "disabled" in v && v.disabled === true;
|
|
44
|
+
}
|
|
45
|
+
// Marker set by defineEntityQueryHandler on both of its verbs. A string, not
|
|
46
|
+
// a Symbol(), for the same reason as PAGED_QUERY_HANDLER_BRAND: a symlinked
|
|
47
|
+
// workspace can evaluate a module twice, and two Symbol() calls would not
|
|
48
|
+
// compare equal across those instances.
|
|
49
|
+
export const ENTITY_CONVENTION_QUERY_BRAND = "__kumikoEntityConventionQuery";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type HookPhase = "inTransaction" | "afterCommit";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { StoredEvent } from "./event-store-types.js";
|
|
2
|
+
import type { AppContext } from "./handlers.js";
|
|
3
|
+
import type { HookPhase } from "./hook-phase.js";
|
|
4
|
+
import type { EntityId } from "./identifiers.js";
|
|
5
|
+
export type ValidationError = {
|
|
6
|
+
readonly field: string;
|
|
7
|
+
readonly error: string;
|
|
8
|
+
};
|
|
9
|
+
export type ValidationHookFn = (data: Readonly<Record<string, unknown>>) => readonly ValidationError[] | null;
|
|
10
|
+
export type SaveContext = {
|
|
11
|
+
readonly kind: "save";
|
|
12
|
+
readonly id: EntityId;
|
|
13
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
14
|
+
readonly changes: Readonly<Record<string, unknown>>;
|
|
15
|
+
readonly previous: Readonly<Record<string, unknown>>;
|
|
16
|
+
readonly isNew: boolean;
|
|
17
|
+
readonly entityName?: string | undefined;
|
|
18
|
+
readonly event?: StoredEvent | undefined;
|
|
19
|
+
};
|
|
20
|
+
export type DeleteContext = {
|
|
21
|
+
readonly kind: "delete";
|
|
22
|
+
readonly id: EntityId;
|
|
23
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
24
|
+
readonly entityName?: string | undefined;
|
|
25
|
+
readonly event?: StoredEvent | undefined;
|
|
26
|
+
};
|
|
27
|
+
export type LifecycleResult = SaveContext | DeleteContext;
|
|
28
|
+
export type PreSaveHookFn = (changes: Record<string, unknown>, context: AppContext & {
|
|
29
|
+
readonly previous: Readonly<Record<string, unknown>>;
|
|
30
|
+
readonly isNew: boolean;
|
|
31
|
+
}) => Promise<Record<string, unknown>>;
|
|
32
|
+
export type PostSaveHookFn = (result: SaveContext, context: AppContext) => Promise<void>;
|
|
33
|
+
export type PostSaveBatchHookFn = (results: readonly SaveContext[], context: AppContext) => Promise<void>;
|
|
34
|
+
export type PreDeleteHookFn = (payload: DeleteContext, context: AppContext) => Promise<void>;
|
|
35
|
+
export type PostDeleteHookFn = (payload: DeleteContext, context: AppContext) => Promise<void>;
|
|
36
|
+
export type PostDeleteBatchHookFn = (payloads: readonly DeleteContext[], context: AppContext) => Promise<void>;
|
|
37
|
+
export type PreQueryHookFn = (payload: Record<string, unknown>, context: AppContext) => Promise<Record<string, unknown>>;
|
|
38
|
+
export type PostQueryHookFn = (result: {
|
|
39
|
+
readonly entityName: string | undefined;
|
|
40
|
+
readonly rows: ReadonlyArray<Record<string, unknown>>;
|
|
41
|
+
}, context: AppContext) => Promise<{
|
|
42
|
+
rows: ReadonlyArray<Record<string, unknown>>;
|
|
43
|
+
}>;
|
|
44
|
+
export type LifecycleHookFn = PreSaveHookFn | PostSaveHookFn | PreDeleteHookFn | PostDeleteHookFn | PreQueryHookFn | PostQueryHookFn;
|
|
45
|
+
export type { HookPhase } from "./hook-phase.js";
|
|
46
|
+
export type HookOwner = {
|
|
47
|
+
readonly featureName?: string;
|
|
48
|
+
};
|
|
49
|
+
export type PhasedHook<TFn> = {
|
|
50
|
+
readonly fn: TFn;
|
|
51
|
+
readonly phase: HookPhase;
|
|
52
|
+
} & HookOwner;
|
|
53
|
+
export type OwnedFn<TFn> = {
|
|
54
|
+
readonly fn: TFn;
|
|
55
|
+
} & HookOwner;
|
|
56
|
+
export type HookMap = {
|
|
57
|
+
readonly validation?: Readonly<Record<string, ValidationHookFn>>;
|
|
58
|
+
readonly preSave?: Readonly<Record<string, readonly OwnedFn<PreSaveHookFn>[]>>;
|
|
59
|
+
readonly postSave?: Readonly<Record<string, readonly PhasedHook<PostSaveHookFn>[]>>;
|
|
60
|
+
readonly preDelete?: Readonly<Record<string, readonly PhasedHook<PreDeleteHookFn>[]>>;
|
|
61
|
+
readonly postDelete?: Readonly<Record<string, readonly PhasedHook<PostDeleteHookFn>[]>>;
|
|
62
|
+
readonly preQuery?: Readonly<Record<string, readonly OwnedFn<PreQueryHookFn>[]>>;
|
|
63
|
+
readonly postQuery?: Readonly<Record<string, readonly OwnedFn<PostQueryHookFn>[]>>;
|
|
64
|
+
};
|
|
65
|
+
export type EntityHookMap = {
|
|
66
|
+
readonly postSave?: Readonly<Record<string, readonly PhasedHook<PostSaveHookFn>[]>>;
|
|
67
|
+
readonly preDelete?: Readonly<Record<string, readonly PhasedHook<PreDeleteHookFn>[]>>;
|
|
68
|
+
readonly postDelete?: Readonly<Record<string, readonly PhasedHook<PostDeleteHookFn>[]>>;
|
|
69
|
+
readonly postQuery?: Readonly<Record<string, readonly OwnedFn<PostQueryHookFn>[]>>;
|
|
70
|
+
};
|
|
71
|
+
export type SearchPayloadContributorFn = (args: {
|
|
72
|
+
readonly entityName: string;
|
|
73
|
+
readonly entityId: EntityId;
|
|
74
|
+
readonly state: Record<string, unknown>;
|
|
75
|
+
}) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
/** Subset von HTTP-Methoden den wir aktiv unterstützen. Hono spricht
|
|
3
|
+
* alle, aber das hier sind die einzigen die ein Feature-Author
|
|
4
|
+
* realistisch deklariert. */
|
|
5
|
+
export type HttpRouteMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
|
|
6
|
+
/** Dependencies die der Handler vom Framework bekommt. App-Author kann
|
|
7
|
+
* die App selbst aufrufen (`deps.app.fetch(...)` für intern-call) oder
|
|
8
|
+
* direkt per dispatcher Daten ziehen. Db/Redis sind die rohen Connections
|
|
9
|
+
* — wer Tenant-Scope braucht muss durch dispatcher.query gehen.
|
|
10
|
+
*
|
|
11
|
+
* Hono-typing: `Context<any, any>` weil das Hono-Type-Param-Setup nur
|
|
12
|
+
* intern relevant ist. Concrete Hono-app wird im Boot-Path zugewiesen. */
|
|
13
|
+
export type HttpRouteHandlerDeps = {
|
|
14
|
+
/** Die Hono-app — Handler kann via app.fetch(...) interne Routes
|
|
15
|
+
* ansprechen (z.B. /api/query mit der vollen Auth-/Anonymous-Chain). */
|
|
16
|
+
readonly app: import("hono").Hono<any, any>;
|
|
17
|
+
/** Run a query handler in-process, forcing a SPECIFIC tenant — WITHOUT
|
|
18
|
+
* going through the public /api/query HTTP layer (no header parsing, no
|
|
19
|
+
* anonymousAccess tenant resolution). The synthesized caller carries
|
|
20
|
+
* anonymous-level access ONLY (same role a real anonymous request would
|
|
21
|
+
* have, no more) — the primitive forces the tenant, not the privilege
|
|
22
|
+
* level, so it stays safe to call from any `anonymous: true` route
|
|
23
|
+
* without risking a field-level disclosure a real anonymous caller
|
|
24
|
+
* couldn't already get. Use this whenever the route needs a tenant
|
|
25
|
+
* other than the one the request resolves to (e.g. always
|
|
26
|
+
* SYSTEM_TENANT_ID regardless of the visited host) — spoofing that via
|
|
27
|
+
* an internal X-Tenant header on `app.fetch(...)` is indistinguishable
|
|
28
|
+
* from an external client and gets rejected by resolverTrust:
|
|
29
|
+
* "authoritative" anonymousAccess configs (see auth-middleware.ts). */
|
|
30
|
+
readonly systemQuery: (type: string, payload: unknown, tenantId: import("./identifiers.js").TenantId) => Promise<unknown>;
|
|
31
|
+
/** Caller IP resolved via the server's configured, trustedProxyHops-aware
|
|
32
|
+
* resolver (same one requestIdMiddleware uses for `/api/*`) — a route
|
|
33
|
+
* handler needing the caller's IP (rate limiting, audit) should read
|
|
34
|
+
* this instead of parsing X-Forwarded-For itself, which trusts
|
|
35
|
+
* whichever hop count the deployment actually has in front of it. */
|
|
36
|
+
readonly clientIp: string;
|
|
37
|
+
};
|
|
38
|
+
export type HttpRouteHandler = (c: Context<any, any>, deps: HttpRouteHandlerDeps) => Response | Promise<Response>;
|
|
39
|
+
export type HttpRouteDefinition = {
|
|
40
|
+
/** HTTP-Methode — bei Hono-Mount via app.{get,post,...}(path). */
|
|
41
|
+
readonly method: HttpRouteMethod;
|
|
42
|
+
/** URL-Pfad (Hono-Pattern, z.B. "/feed.xml" oder "/og/:tenantId.png"). */
|
|
43
|
+
readonly path: string;
|
|
44
|
+
/** true = public, no session required. false = mounted behind the
|
|
45
|
+
* session auth chain (no anonymous fallthrough, PAT rate limit,
|
|
46
|
+
* origin + CSRF guards) — a request without a session gets 401. The
|
|
47
|
+
* handler reads the caller via getUser(c). */
|
|
48
|
+
readonly anonymous: boolean;
|
|
49
|
+
/** Hono-Handler. Bekommt Hono-Context + Framework-Deps; returnt
|
|
50
|
+
* Response (sync oder async). */
|
|
51
|
+
readonly handler: HttpRouteHandler;
|
|
52
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// HTTP route definition — feature-declared HTTP endpoints outside
|
|
2
|
+
// the /api/write|query|batch pipeline. Use case: RSS/Atom feeds, OpenAPI
|
|
3
|
+
// specs, OG image generators, webhook receivers — anything where the
|
|
4
|
+
// feature author controls the wire format themselves.
|
|
5
|
+
//
|
|
6
|
+
// Pattern symmetric to r.queryHandler / r.writeHandler: definition as
|
|
7
|
+
// part of the feature (not the app bootstrapping). Phase-3 multi-tenant
|
|
8
|
+
// becomes trivial because tenant context is picked up via host resolution.
|
|
9
|
+
//
|
|
10
|
+
// Escape-hatch stays: runProdApp.extraRoutes (declarative list with
|
|
11
|
+
// `entry` tier) for hand-rolled routes that have nothing to do with a
|
|
12
|
+
// feature (e.g. platform-specific static-serving logic).
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type TenantId = string;
|
|
2
|
+
export declare const UUID_SHAPE_PATTERN = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
|
|
3
|
+
export declare function isUuid(value: unknown): value is string;
|
|
4
|
+
export declare function parseTenantId(value: unknown): TenantId | null;
|
|
5
|
+
export declare const SYSTEM_TENANT_ID: TenantId;
|
|
6
|
+
export declare function isSystemTenant(tenantId: TenantId | null | undefined): boolean;
|
|
7
|
+
export declare const SYSTEM_USER_ID = "00000000-0000-0000-0000-000000000000";
|
|
8
|
+
export type EntityId = number | string;
|
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
// travels through the framework. One declaration per concept so future
|
|
3
3
|
// representation changes (branded types, UUID validation, opaque wrappers)
|
|
4
4
|
// land in a single place.
|
|
5
|
-
|
|
6
|
-
// Tenant identifier — UUID string today. May become branded/opaque later
|
|
7
|
-
// without touching call sites.
|
|
8
|
-
export type TenantId = string;
|
|
9
|
-
|
|
10
5
|
// Lowercase UUID (any RFC-4122 variant). Strict enough to keep client-
|
|
11
6
|
// supplied junk (e.g. SQL fragments, path-traversal probes) out of the
|
|
12
7
|
// pipeline; loose enough that v4 / v7 / nil all match. Any caller that
|
|
@@ -18,46 +13,34 @@ export type TenantId = string;
|
|
|
18
13
|
// exact same shape instead of growing a second copy that drifts.
|
|
19
14
|
export const UUID_SHAPE_PATTERN = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
|
|
20
15
|
const TENANT_ID_REGEX = new RegExp(UUID_SHAPE_PATTERN);
|
|
21
|
-
|
|
22
16
|
// Shared shape check for any UUID-formatted identifier crossing an
|
|
23
17
|
// untrusted boundary (fileRefId, entity ids, ...) — same loose,
|
|
24
18
|
// version-agnostic regex as TENANT_ID_REGEX (v4/v7/nil all match), kept as
|
|
25
19
|
// one predicate so call sites don't grow their own copy of the shape.
|
|
26
|
-
export function isUuid(value
|
|
27
|
-
|
|
20
|
+
export function isUuid(value) {
|
|
21
|
+
return typeof value === "string" && TENANT_ID_REGEX.test(value);
|
|
28
22
|
}
|
|
29
|
-
|
|
30
23
|
// Validates a candidate string against the tenantId format and returns it
|
|
31
24
|
// as a TenantId, or `null` when it doesn't match. Use at every system
|
|
32
25
|
// boundary that admits untrusted input (HTTP headers, cookies, query
|
|
33
26
|
// params). Returning null instead of throwing keeps the caller in charge
|
|
34
27
|
// of the rejection shape — middleware returns 400, batch jobs may filter
|
|
35
28
|
// + log, and unit tests don't need a try/catch.
|
|
36
|
-
export function parseTenantId(value
|
|
37
|
-
|
|
29
|
+
export function parseTenantId(value) {
|
|
30
|
+
return isUuid(value) ? value : null;
|
|
38
31
|
}
|
|
39
|
-
|
|
40
32
|
// "System-scope" tenant marker: handlers carry this tenantId when the event
|
|
41
33
|
// doesn't belong to any particular tenant (reference data, cross-tenant
|
|
42
34
|
// jobs, global config). The concrete UUID is a valid v4 (not all-zeroes —
|
|
43
35
|
// Postgres' UUID type rejects invalid variants), chosen to be easy to
|
|
44
36
|
// eyeball in logs. Central constant so call sites don't re-type the string
|
|
45
37
|
// and the isSystemTenant() check stays in sync.
|
|
46
|
-
export const SYSTEM_TENANT_ID
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return !tenantId || tenantId === SYSTEM_TENANT_ID;
|
|
38
|
+
export const SYSTEM_TENANT_ID = "00000000-0000-4000-8000-000000000000";
|
|
39
|
+
export function isSystemTenant(tenantId) {
|
|
40
|
+
return !tenantId || tenantId === SYSTEM_TENANT_ID;
|
|
50
41
|
}
|
|
51
|
-
|
|
52
42
|
// "No human caller" marker on event-store `createdBy`. Stringified so it
|
|
53
43
|
// round-trips through SessionUser.id; not a real UUID, and createdBy is text.
|
|
54
44
|
// Lives here rather than next to createSystemUser() so client-side code (the
|
|
55
45
|
// reference-label map) can read it without importing a runtime module.
|
|
56
46
|
export const SYSTEM_USER_ID = "00000000-0000-0000-0000-000000000000";
|
|
57
|
-
|
|
58
|
-
// Primary-key identifier for any entity row. Two shapes coexist because of
|
|
59
|
-
// the entity-def `idType` switch: classic CRUD entities keep `serial` (number),
|
|
60
|
-
// while tenant + ES aggregates run on `uuid` (string). Call sites that pass
|
|
61
|
-
// the id through to the DB layer stay agnostic; only code that formats ids
|
|
62
|
-
// for URLs, logs, or cache keys needs `String(id)` — JS coerces both safely.
|
|
63
|
-
export type EntityId = number | string;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { TenantId } from "./identifiers.js";
|
|
2
|
+
export type SubjectId = {
|
|
3
|
+
readonly kind: "user";
|
|
4
|
+
readonly userId: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: "tenant";
|
|
7
|
+
readonly tenantId: TenantId;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "record";
|
|
10
|
+
readonly entity: string;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
};
|
|
13
|
+
export type SubjectKey = string;
|
|
14
|
+
export declare function subjectKeyForUser(userId: string): SubjectKey;
|
|
15
|
+
export declare function subjectKeyForTenant(tenantId: TenantId): SubjectKey;
|
|
16
|
+
export declare const RECORD_ENTITY_PATTERN: RegExp;
|
|
17
|
+
export declare function subjectKeyForRecord(entity: string, id: string): SubjectKey;
|
|
18
|
+
export declare function subjectIdToKey(subject: SubjectId): SubjectKey;
|
|
19
|
+
export declare function subjectIdFromKey(key: SubjectKey): SubjectId;
|
|
20
|
+
export interface KmsContext {
|
|
21
|
+
readonly tenantId?: TenantId;
|
|
22
|
+
readonly requestId: string;
|
|
23
|
+
readonly userId?: string;
|
|
24
|
+
readonly eraseReason?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface KmsHealth {
|
|
27
|
+
readonly ok: boolean;
|
|
28
|
+
readonly latencyMs: number;
|
|
29
|
+
readonly details?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
export type SubjectDek = Buffer;
|
|
32
|
+
interface KmsAdapterBase {
|
|
33
|
+
/**
|
|
34
|
+
* Creates a fresh subject key. Throws KeyAlreadyExistsError when the
|
|
35
|
+
* subject already has one — including an erased tombstone: a shredded
|
|
36
|
+
* subject must never get a new key, or forget could be undone by
|
|
37
|
+
* re-encrypting under it.
|
|
38
|
+
*/
|
|
39
|
+
createKey(subject: SubjectId, ctx: KmsContext): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Erases the key material immediately; the tombstone row stays for the
|
|
42
|
+
* audit trail. Idempotent — repeat calls and unknown subjects are no-ops.
|
|
43
|
+
*/
|
|
44
|
+
eraseKey(subject: SubjectId, ctx: KmsContext): Promise<void>;
|
|
45
|
+
/** Probe for boot + readiness. Throws when the backend is unreachable. */
|
|
46
|
+
health(): Promise<KmsHealth>;
|
|
47
|
+
}
|
|
48
|
+
export interface LocalKeyKmsAdapter extends KmsAdapterBase {
|
|
49
|
+
readonly capabilities: {
|
|
50
|
+
readonly mode: "local-key";
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Throws KeyErasedError after eraseKey (callers render "[[erased]]"),
|
|
54
|
+
* KeyNotFoundError when the subject never had a key (typically a bug).
|
|
55
|
+
*/
|
|
56
|
+
getKey(subject: SubjectId, ctx: KmsContext): Promise<SubjectDek>;
|
|
57
|
+
}
|
|
58
|
+
export interface RemoteCryptoKmsAdapter extends KmsAdapterBase {
|
|
59
|
+
readonly capabilities: {
|
|
60
|
+
readonly mode: "remote-crypto";
|
|
61
|
+
};
|
|
62
|
+
encrypt(subject: SubjectId, plaintext: Uint8Array, ctx: KmsContext): Promise<Uint8Array>;
|
|
63
|
+
/** Same error contract as LocalKeyKmsAdapter.getKey. */
|
|
64
|
+
decrypt(subject: SubjectId, ciphertext: Uint8Array, ctx: KmsContext): Promise<Uint8Array>;
|
|
65
|
+
}
|
|
66
|
+
export type KmsAdapter = LocalKeyKmsAdapter | RemoteCryptoKmsAdapter;
|
|
67
|
+
export declare function isLocalKeyKmsAdapter(adapter: KmsAdapter): adapter is LocalKeyKmsAdapter;
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function subjectKeyForUser(userId) {
|
|
2
|
+
return `user:${userId}`;
|
|
3
|
+
}
|
|
4
|
+
export function subjectKeyForTenant(tenantId) {
|
|
5
|
+
return `tenant:${tenantId}`;
|
|
6
|
+
}
|
|
7
|
+
// Registry entity names are identifier-shaped; a free-form aggregate_type
|
|
8
|
+
// (events-schema.ts is a plain text column) could otherwise mint a record
|
|
9
|
+
// key that subjectIdSchema (forget-subject.write.ts) later refuses to
|
|
10
|
+
// shred — enforced once here so minting and shredding can never disagree.
|
|
11
|
+
export const RECORD_ENTITY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;
|
|
12
|
+
export function subjectKeyForRecord(entity, id) {
|
|
13
|
+
if (!RECORD_ENTITY_PATTERN.test(entity)) {
|
|
14
|
+
throw new Error(`Invalid record entity for subject key: "${entity}" — must match ${RECORD_ENTITY_PATTERN}`);
|
|
15
|
+
}
|
|
16
|
+
if (id === "")
|
|
17
|
+
throw new Error("Invalid record id for subject key: empty");
|
|
18
|
+
return `record:${entity}:${id}`;
|
|
19
|
+
}
|
|
20
|
+
export function subjectIdToKey(subject) {
|
|
21
|
+
switch (subject.kind) {
|
|
22
|
+
case "user":
|
|
23
|
+
return subjectKeyForUser(subject.userId);
|
|
24
|
+
case "tenant":
|
|
25
|
+
return subjectKeyForTenant(subject.tenantId);
|
|
26
|
+
case "record":
|
|
27
|
+
return subjectKeyForRecord(subject.entity, subject.id);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function subjectIdFromKey(key) {
|
|
31
|
+
if (key.startsWith("user:"))
|
|
32
|
+
return { kind: "user", userId: key.slice("user:".length) };
|
|
33
|
+
if (key.startsWith("tenant:")) {
|
|
34
|
+
return { kind: "tenant", tenantId: key.slice("tenant:".length) }; // @cast-boundary parse of a key this module minted
|
|
35
|
+
}
|
|
36
|
+
if (key.startsWith("record:")) {
|
|
37
|
+
const rest = key.slice("record:".length);
|
|
38
|
+
const separatorIndex = rest.indexOf(":");
|
|
39
|
+
const entity = separatorIndex === -1 ? "" : rest.slice(0, separatorIndex);
|
|
40
|
+
const id = separatorIndex === -1 ? "" : rest.slice(separatorIndex + 1);
|
|
41
|
+
if (entity === "" || id === "")
|
|
42
|
+
throw new Error(`Invalid subject key: ${key}`);
|
|
43
|
+
return { kind: "record", entity, id };
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`Invalid subject key: ${key}`);
|
|
46
|
+
}
|
|
47
|
+
export function isLocalKeyKmsAdapter(adapter) {
|
|
48
|
+
return adapter.capabilities.mode === "local-key";
|
|
49
|
+
}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type Logger = {
|
|
2
|
+
info(msg: string, data?: Record<string, unknown>): void;
|
|
3
|
+
warn(msg: string, data?: Record<string, unknown>): void;
|
|
4
|
+
error(msg: string, data?: Record<string, unknown>): void;
|
|
5
|
+
debug(msg: string, data?: Record<string, unknown>): void;
|
|
6
|
+
child(context: Record<string, unknown>): Logger;
|
|
7
|
+
};
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DerivativesContext } from "./derivatives-types.js";
|
|
2
|
+
import type { StoredEvent } from "./event-store-types.js";
|
|
3
|
+
import type { KumikoEventTypeMap } from "./event-type-map.js";
|
|
4
|
+
import type { Registry } from "./feature.js";
|
|
5
|
+
import type { FileContext } from "./file-handle-types.js";
|
|
6
|
+
import type { AppendEventFn, UnsafeAppendEventFn } from "./handlers.js";
|
|
7
|
+
import type { SecretsContext } from "./secrets-types.js";
|
|
8
|
+
export type MultiStreamApplyContext<TMap extends object = KumikoEventTypeMap> = {
|
|
9
|
+
readonly appendEvent: AppendEventFn<TMap>;
|
|
10
|
+
readonly unsafeAppendEvent: UnsafeAppendEventFn;
|
|
11
|
+
readonly loadAggregate: (aggregateId: string, options?: {
|
|
12
|
+
readonly asOf?: Temporal.Instant;
|
|
13
|
+
}) => Promise<readonly StoredEvent[]>;
|
|
14
|
+
readonly registry: Registry;
|
|
15
|
+
readonly files?: FileContext;
|
|
16
|
+
readonly derivatives?: DerivativesContext;
|
|
17
|
+
readonly secrets?: SecretsContext;
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const NAV_ICON_KEYS: readonly ["dashboard", "layout-grid", "book-open", "clipboard-list", "package", "gauge", "list", "table", "layers", "building", "calculator", "wallet", "coins", "credit-card", "piggy-bank", "receipt", "chart", "bar-chart", "trending", "sparkles", "wand", "calendar", "file", "folder", "folder-open", "home", "bell", "shield", "shield-check", "send", "settings", "users", "user", "search", "tag", "key", "link", "palette", "share", "server", "mail", "lock", "hash", "download", "upload", "rocket", "plus", "languages", "trash", "x", "check", "arrow-left", "arrow-right", "copy", "pencil", "eye", "eye-off", "filter", "refresh", "more-horizontal", "more-vertical", "external-link", "chevron-down", "chevron-left", "chevron-right", "save", "undo", "archive", "star", "flag", "clock", "map-pin", "phone", "printer", "alert-triangle", "info", "check-circle", "x-circle", "loader", "mic", "circle-stop", "image"];
|
|
2
|
+
export type NavIconKey = (typeof NAV_ICON_KEYS)[number];
|
|
3
|
+
export type IconKey = NavIconKey;
|
package/dist/nav-icon.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Closed vocabulary of nav and button icon keys. NavDefinition.icon,
|
|
2
|
+
// ScreenNavSugar.icon, ConfigMask.icon and ButtonProps.icon/iconEnd are all
|
|
3
|
+
// typed against this union, so an unregistered key is a compile error at the
|
|
4
|
+
// r.nav()/r.screen()/config-mask/button call site instead of a silent
|
|
5
|
+
// missing-icon at runtime.
|
|
6
|
+
//
|
|
7
|
+
// The renderer-web NAV_ICONS map (packages/renderer-web/src/icons.tsx) is
|
|
8
|
+
// checked against this same union via `satisfies`, so the two can't drift —
|
|
9
|
+
// add a key here only together with its lucide-react entry there, and vice
|
|
10
|
+
// versa.
|
|
11
|
+
//
|
|
12
|
+
// Declared as a runtime tuple (not just a type) so callers that sit outside
|
|
13
|
+
// this repo's `tsc --build` project graph (e.g. samples, external consumers
|
|
14
|
+
// resolving from a stale published type) still get a runtime-checkable
|
|
15
|
+
// vocabulary — the boot-validator's validateActionHasIcon checks a declared
|
|
16
|
+
// icon against NAV_ICON_KEYS instead of trusting "not undefined".
|
|
17
|
+
export const NAV_ICON_KEYS = [
|
|
18
|
+
"dashboard",
|
|
19
|
+
"layout-grid",
|
|
20
|
+
"book-open",
|
|
21
|
+
"clipboard-list",
|
|
22
|
+
"package",
|
|
23
|
+
"gauge",
|
|
24
|
+
"list",
|
|
25
|
+
"table",
|
|
26
|
+
"layers",
|
|
27
|
+
"building",
|
|
28
|
+
"calculator",
|
|
29
|
+
"wallet",
|
|
30
|
+
"coins",
|
|
31
|
+
"credit-card",
|
|
32
|
+
"piggy-bank",
|
|
33
|
+
"receipt",
|
|
34
|
+
"chart",
|
|
35
|
+
"bar-chart",
|
|
36
|
+
"trending",
|
|
37
|
+
"sparkles",
|
|
38
|
+
"wand",
|
|
39
|
+
"calendar",
|
|
40
|
+
"file",
|
|
41
|
+
"folder",
|
|
42
|
+
"folder-open",
|
|
43
|
+
"home",
|
|
44
|
+
"bell",
|
|
45
|
+
"shield",
|
|
46
|
+
"shield-check",
|
|
47
|
+
"send",
|
|
48
|
+
"settings",
|
|
49
|
+
"users",
|
|
50
|
+
"user",
|
|
51
|
+
"search",
|
|
52
|
+
"tag",
|
|
53
|
+
"key",
|
|
54
|
+
"link",
|
|
55
|
+
"palette",
|
|
56
|
+
"share",
|
|
57
|
+
"server",
|
|
58
|
+
"mail",
|
|
59
|
+
"lock",
|
|
60
|
+
"hash",
|
|
61
|
+
"download",
|
|
62
|
+
"upload",
|
|
63
|
+
"rocket",
|
|
64
|
+
"plus",
|
|
65
|
+
"languages",
|
|
66
|
+
"trash",
|
|
67
|
+
"x",
|
|
68
|
+
"check",
|
|
69
|
+
"arrow-left",
|
|
70
|
+
"arrow-right",
|
|
71
|
+
"copy",
|
|
72
|
+
"pencil",
|
|
73
|
+
"eye",
|
|
74
|
+
"eye-off",
|
|
75
|
+
"filter",
|
|
76
|
+
"refresh",
|
|
77
|
+
"more-horizontal",
|
|
78
|
+
"more-vertical",
|
|
79
|
+
"external-link",
|
|
80
|
+
"chevron-down",
|
|
81
|
+
"chevron-left",
|
|
82
|
+
"chevron-right",
|
|
83
|
+
"save",
|
|
84
|
+
"undo",
|
|
85
|
+
"archive",
|
|
86
|
+
"star",
|
|
87
|
+
"flag",
|
|
88
|
+
"clock",
|
|
89
|
+
"map-pin",
|
|
90
|
+
"phone",
|
|
91
|
+
"printer",
|
|
92
|
+
"alert-triangle",
|
|
93
|
+
"info",
|
|
94
|
+
"check-circle",
|
|
95
|
+
"x-circle",
|
|
96
|
+
"loader",
|
|
97
|
+
"mic",
|
|
98
|
+
"circle-stop",
|
|
99
|
+
"image",
|
|
100
|
+
];
|
package/dist/nav.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AccessRule } from "./handlers.js";
|
|
2
|
+
import type { NavIconKey } from "./nav-icon.js";
|
|
3
|
+
import type { TargetRef } from "./target-ref.js";
|
|
4
|
+
import type { TreeAction } from "./tree-node.js";
|
|
5
|
+
export type { IconKey, NavIconKey } from "./nav-icon.js";
|
|
6
|
+
export type NavDefinition = {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly label: string;
|
|
9
|
+
readonly icon?: NavIconKey;
|
|
10
|
+
readonly parent?: string;
|
|
11
|
+
readonly order?: number;
|
|
12
|
+
readonly screen?: string;
|
|
13
|
+
readonly target?: TargetRef;
|
|
14
|
+
readonly actions?: readonly TreeAction[];
|
|
15
|
+
readonly createAction?: TreeAction;
|
|
16
|
+
readonly provider?: boolean;
|
|
17
|
+
readonly access?: AccessRule;
|
|
18
|
+
readonly workspaces?: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
/** Client editor format for r.contentCollection() — not template body storage formats. */
|
|
21
|
+
export type ContentEditorFormat = "plain" | "rich" | "markdown";
|
|
22
|
+
export type ContentCollectionDefinition = {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly kind: string;
|
|
25
|
+
readonly access?: AccessRule;
|
|
26
|
+
readonly ownership?: "tenant" | "user";
|
|
27
|
+
readonly contentFormat?: ContentEditorFormat;
|
|
28
|
+
readonly variableSchema?: Readonly<Record<string, string>>;
|
|
29
|
+
readonly nav: {
|
|
30
|
+
readonly label: string;
|
|
31
|
+
readonly icon?: NavIconKey;
|
|
32
|
+
readonly parent?: string;
|
|
33
|
+
readonly order?: number;
|
|
34
|
+
readonly access?: AccessRule;
|
|
35
|
+
readonly workspaces?: readonly string[];
|
|
36
|
+
readonly createAction?: TreeAction;
|
|
37
|
+
readonly actions?: readonly TreeAction[];
|
|
38
|
+
};
|
|
39
|
+
};
|
package/dist/nav.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { Counter, Gauge, Histogram, Meter, MetricDefinition, MetricLabels, MetricsHandle, MetricType, } from "./metric.js";
|
|
2
|
+
export type { ObservabilityOptions, ObservabilityProvider, SamplingConfig, SensitiveFilterConfig, } from "./provider.js";
|
|
3
|
+
export type { SerializedTraceContext, Span, SpanAttributes, SpanAttributeValue, SpanKind, SpanStatus, StartSpanOptions, Tracer, } from "./span.js";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type MetricLabels = Record<string, string | number | boolean>;
|
|
2
|
+
export type MetricType = "counter" | "histogram" | "gauge";
|
|
3
|
+
export type MetricDefinition = {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly type: MetricType;
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
readonly labels?: readonly string[];
|
|
8
|
+
readonly buckets?: readonly number[];
|
|
9
|
+
readonly unit?: string;
|
|
10
|
+
readonly tenantLabel?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export interface Counter {
|
|
13
|
+
inc(value?: number, labels?: MetricLabels): void;
|
|
14
|
+
}
|
|
15
|
+
export interface Histogram {
|
|
16
|
+
observe(value: number, labels?: MetricLabels): void;
|
|
17
|
+
}
|
|
18
|
+
export interface Gauge {
|
|
19
|
+
set(value: number, labels?: MetricLabels): void;
|
|
20
|
+
inc(value?: number, labels?: MetricLabels): void;
|
|
21
|
+
dec(value?: number, labels?: MetricLabels): void;
|
|
22
|
+
}
|
|
23
|
+
export interface Meter {
|
|
24
|
+
registerMetric(def: MetricDefinition): void;
|
|
25
|
+
counter(name: string): Counter;
|
|
26
|
+
histogram(name: string): Histogram;
|
|
27
|
+
gauge(name: string): Gauge;
|
|
28
|
+
definitions(): ReadonlyMap<string, MetricDefinition>;
|
|
29
|
+
}
|
|
30
|
+
export interface MetricsHandle {
|
|
31
|
+
inc(name: string, labels?: MetricLabels, value?: number): void;
|
|
32
|
+
observe(name: string, value: number, labels?: MetricLabels): void;
|
|
33
|
+
set(name: string, value: number, labels?: MetricLabels): void;
|
|
34
|
+
}
|