@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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Part B (fw-ui-defaults): id-derived default icon for actions that never
|
|
2
|
+
// declared one — a screen author still gets a recognizable glyph instead of
|
|
3
|
+
// a bare label. Checked against the actually registered IconKey vocabulary
|
|
4
|
+
// (nav-icon.ts) — no entry for verbs without a matching icon (e.g. "start",
|
|
5
|
+
// "pause").
|
|
6
|
+
export const ACTION_ICON_BY_ID = {
|
|
7
|
+
delete: "trash",
|
|
8
|
+
deletion: "trash",
|
|
9
|
+
edit: "pencil",
|
|
10
|
+
create: "plus",
|
|
11
|
+
new: "plus",
|
|
12
|
+
add: "plus",
|
|
13
|
+
view: "eye",
|
|
14
|
+
open: "eye",
|
|
15
|
+
cancel: "x",
|
|
16
|
+
reject: "x",
|
|
17
|
+
complete: "check",
|
|
18
|
+
resolve: "check",
|
|
19
|
+
approve: "check",
|
|
20
|
+
archive: "archive",
|
|
21
|
+
publish: "upload",
|
|
22
|
+
duplicate: "copy",
|
|
23
|
+
copy: "copy",
|
|
24
|
+
download: "download",
|
|
25
|
+
refresh: "refresh",
|
|
26
|
+
retry: "refresh",
|
|
27
|
+
settings: "settings",
|
|
28
|
+
share: "share",
|
|
29
|
+
send: "send",
|
|
30
|
+
};
|
|
31
|
+
// Ids are kebab-case (RowAction.id doc): aggregate-object-verb
|
|
32
|
+
// ("order-ship") or verb-prefix ("add-item").
|
|
33
|
+
function kebabLastSegment(id) {
|
|
34
|
+
const idx = id.lastIndexOf("-");
|
|
35
|
+
return idx === -1 ? id : id.slice(idx + 1);
|
|
36
|
+
}
|
|
37
|
+
function kebabFirstSegment(id) {
|
|
38
|
+
const idx = id.indexOf("-");
|
|
39
|
+
return idx === -1 ? id : id.slice(0, idx);
|
|
40
|
+
}
|
|
41
|
+
// Resolution order: author-declared `icon` wins, then the id-derived
|
|
42
|
+
// default (full id, then its last kebab segment, then its first kebab
|
|
43
|
+
// segment). `declared` is `undefined` for ToolbarAction, which has no
|
|
44
|
+
// author-facing icon field.
|
|
45
|
+
export function resolveActionIcon(id, declared) {
|
|
46
|
+
if (declared !== undefined)
|
|
47
|
+
return declared;
|
|
48
|
+
return (ACTION_ICON_BY_ID[id] ??
|
|
49
|
+
ACTION_ICON_BY_ID[kebabLastSegment(id)] ??
|
|
50
|
+
ACTION_ICON_BY_ID[kebabFirstSegment(id)]);
|
|
51
|
+
}
|
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
import type { AgentExposure, AgentHandlerHints } from "./handlers";
|
|
2
|
-
|
|
1
|
+
import type { AgentExposure, AgentHandlerHints } from "./handlers.js";
|
|
3
2
|
/** Fail-closed: a handler without a `description` stays invisible to the agent
|
|
4
3
|
* unless it opts in explicitly. `kind` is a parameter because write and query
|
|
5
4
|
* handler definitions are structurally indistinguishable at runtime. */
|
|
6
|
-
export function resolveAgentExposure(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
): AgentExposure
|
|
10
|
-
return {
|
|
11
|
-
expose: def.agent?.expose ?? def.description !== undefined,
|
|
12
|
-
risk: def.agent?.risk ?? (kind === "query" ? "low" : "mid"),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
5
|
+
export declare function resolveAgentExposure(def: {
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
readonly agent?: AgentHandlerHints;
|
|
8
|
+
}, kind: "query" | "write"): AgentExposure;
|
|
16
9
|
/** Screens are the inverse of handlers: the manifest lists every role-visible
|
|
17
10
|
* screen regardless of `description`, so only an explicit opt-out hides one.
|
|
18
11
|
* Reusing `resolveAgentExposure`'s fail-closed default here would silently
|
|
19
12
|
* drop every screen without a description from the agent's view. */
|
|
20
|
-
export function isAgentVisibleScreen(screen: {
|
|
21
|
-
|
|
22
|
-
}
|
|
13
|
+
export declare function isAgentVisibleScreen(screen: {
|
|
14
|
+
readonly agent?: AgentHandlerHints;
|
|
15
|
+
}): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Fail-closed: a handler without a `description` stays invisible to the agent
|
|
2
|
+
* unless it opts in explicitly. `kind` is a parameter because write and query
|
|
3
|
+
* handler definitions are structurally indistinguishable at runtime. */
|
|
4
|
+
export function resolveAgentExposure(def, kind) {
|
|
5
|
+
return {
|
|
6
|
+
expose: def.agent?.expose ?? def.description !== undefined,
|
|
7
|
+
risk: def.agent?.risk ?? (kind === "query" ? "low" : "mid"),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/** Screens are the inverse of handlers: the manifest lists every role-visible
|
|
11
|
+
* screen regardless of `description`, so only an explicit opt-out hides one.
|
|
12
|
+
* Reusing `resolveAgentExposure`'s fail-closed default here would silently
|
|
13
|
+
* drop every screen without a description from the agent's view. */
|
|
14
|
+
export function isAgentVisibleScreen(screen) {
|
|
15
|
+
return screen.agent?.expose !== false;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ConcurrencyMode = "parallel" | "skip" | "replace" | "sequential" | "debounce";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ConfigScope = "system" | "tenant" | "user";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { ConcurrencyMode } from "./concurrency-mode.js";
|
|
3
|
+
import type { ConfigScope } from "./config-scope.js";
|
|
4
|
+
import type { DbConnection } from "./db-connection.js";
|
|
5
|
+
import type { FieldDefinition } from "./fields.js";
|
|
6
|
+
import type { EscapeHatchDeclaration, JobContext } from "./handlers.js";
|
|
7
|
+
import type { PostDeleteHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn } from "./hooks.js";
|
|
8
|
+
import type { TenantId } from "./identifiers.js";
|
|
9
|
+
import type { NavIconKey } from "./nav-icon.js";
|
|
10
|
+
import type { TenantDb } from "./tenant-db-types.js";
|
|
11
|
+
export type ConfigKeyAccess = {
|
|
12
|
+
readonly read: readonly string[];
|
|
13
|
+
readonly write: readonly string[];
|
|
14
|
+
};
|
|
15
|
+
export type ConfigKeyType = "text" | "number" | "boolean" | "select";
|
|
16
|
+
export type ConfigValue<T extends ConfigKeyType> = T extends "number" ? number : T extends "boolean" ? boolean : T extends "text" | "select" ? string : never;
|
|
17
|
+
export type ConfigBounds = {
|
|
18
|
+
readonly min?: number;
|
|
19
|
+
readonly max?: number;
|
|
20
|
+
};
|
|
21
|
+
export type ConfigComputedContext = {
|
|
22
|
+
readonly tenantId: TenantId;
|
|
23
|
+
readonly userId: string;
|
|
24
|
+
readonly db: DbConnection | TenantDb;
|
|
25
|
+
};
|
|
26
|
+
export type ConfigComputedFn<T extends ConfigKeyType = ConfigKeyType> = (ctx: ConfigComputedContext) => Promise<ConfigValue<T>>;
|
|
27
|
+
export type ConfigBacking = "config" | "secrets";
|
|
28
|
+
export type ConfigSecretsReader = {
|
|
29
|
+
get(tenantId: TenantId, key: string): Promise<{
|
|
30
|
+
readonly reveal: () => string;
|
|
31
|
+
} | undefined>;
|
|
32
|
+
};
|
|
33
|
+
export type ConfigKeyDefinition<T extends ConfigKeyType = ConfigKeyType> = {
|
|
34
|
+
readonly type: T;
|
|
35
|
+
readonly default?: ConfigValue<T>;
|
|
36
|
+
readonly scope: ConfigScope;
|
|
37
|
+
readonly access: ConfigKeyAccess;
|
|
38
|
+
readonly encrypted?: boolean;
|
|
39
|
+
/** User/admin may legitimately see the value — unlike `encrypted`
|
|
40
|
+
* (shared master-key cipher), this is the subject-KMS: the value is
|
|
41
|
+
* encrypted under the DEK of the scope actually written to (tenant-row
|
|
42
|
+
* → tenant subject, user-row → user subject). Only on `type: "text"`,
|
|
43
|
+
* `scope !== "system"` (no subject there), and mutually exclusive with
|
|
44
|
+
* `encrypted` (kumiko-platform#231/#459). */
|
|
45
|
+
readonly piiEncrypted?: boolean;
|
|
46
|
+
readonly options?: readonly string[];
|
|
47
|
+
readonly bounds?: ConfigBounds;
|
|
48
|
+
readonly pattern?: {
|
|
49
|
+
readonly regex: string;
|
|
50
|
+
readonly flags?: string;
|
|
51
|
+
};
|
|
52
|
+
readonly computed?: ConfigComputedFn<T>;
|
|
53
|
+
readonly allowPerRequest?: boolean;
|
|
54
|
+
readonly required?: boolean;
|
|
55
|
+
readonly env?: string;
|
|
56
|
+
readonly inheritedToTenant?: boolean;
|
|
57
|
+
readonly backing?: ConfigBacking;
|
|
58
|
+
readonly mask?: ConfigMask;
|
|
59
|
+
readonly group?: string;
|
|
60
|
+
};
|
|
61
|
+
export type ConfigMask = {
|
|
62
|
+
readonly title: string;
|
|
63
|
+
readonly icon?: NavIconKey;
|
|
64
|
+
readonly order?: number;
|
|
65
|
+
};
|
|
66
|
+
export type ConfigDefinition = {
|
|
67
|
+
readonly keys: Readonly<Record<string, ConfigKeyDefinition>>;
|
|
68
|
+
};
|
|
69
|
+
export type ConfigKeyHandle<T extends ConfigKeyType = ConfigKeyType> = {
|
|
70
|
+
readonly name: string;
|
|
71
|
+
readonly type: T;
|
|
72
|
+
};
|
|
73
|
+
export type ConfigAccessor = {
|
|
74
|
+
(qualifiedKey: string): Promise<string | number | boolean | undefined>;
|
|
75
|
+
<T extends ConfigKeyType>(handle: ConfigKeyHandle<T>): Promise<ConfigValue<T> | undefined>;
|
|
76
|
+
};
|
|
77
|
+
export type ConfigAccessorFactory = (deps: {
|
|
78
|
+
readonly user: {
|
|
79
|
+
readonly id: string;
|
|
80
|
+
readonly tenantId: TenantId;
|
|
81
|
+
};
|
|
82
|
+
readonly db: DbConnection | TenantDb;
|
|
83
|
+
readonly secrets?: ConfigSecretsReader;
|
|
84
|
+
}) => ConfigAccessor;
|
|
85
|
+
export type ConfigStoredRow = {
|
|
86
|
+
readonly id: string;
|
|
87
|
+
readonly key: string;
|
|
88
|
+
readonly value: string | null;
|
|
89
|
+
readonly tenantId: string;
|
|
90
|
+
readonly userId: string | null;
|
|
91
|
+
};
|
|
92
|
+
export type ConfigStoredRowWithSource = ConfigStoredRow & {
|
|
93
|
+
readonly source: ConfigValueSource;
|
|
94
|
+
};
|
|
95
|
+
export type ConfigValueSource = "user-row" | "tenant-row" | "system-row" | "app-override" | "computed" | "default" | "missing";
|
|
96
|
+
export type ConfigValueWithSource = {
|
|
97
|
+
readonly value: string | number | boolean | undefined;
|
|
98
|
+
readonly source: ConfigValueSource;
|
|
99
|
+
};
|
|
100
|
+
export type ConfigCascadeLevel = {
|
|
101
|
+
readonly label: string;
|
|
102
|
+
readonly value: string | number | boolean | undefined;
|
|
103
|
+
readonly source: ConfigValueSource;
|
|
104
|
+
readonly isActive: boolean;
|
|
105
|
+
readonly hasValue: boolean;
|
|
106
|
+
};
|
|
107
|
+
export type ConfigCascade = {
|
|
108
|
+
readonly value: string | number | boolean | undefined;
|
|
109
|
+
readonly source: ConfigValueSource;
|
|
110
|
+
readonly levels: readonly ConfigCascadeLevel[];
|
|
111
|
+
};
|
|
112
|
+
export type ConfigResolver = {
|
|
113
|
+
get(qualifiedKey: string, keyDef: ConfigKeyDefinition, tenantId: TenantId, userId: string, db: DbConnection | TenantDb, secretsReader?: ConfigSecretsReader): Promise<string | number | boolean | undefined>;
|
|
114
|
+
getWithSource(qualifiedKey: string, keyDef: ConfigKeyDefinition, tenantId: TenantId, userId: string, db: DbConnection | TenantDb, secretsReader?: ConfigSecretsReader): Promise<ConfigValueWithSource>;
|
|
115
|
+
getAll(tenantId: TenantId, userId: string, db: DbConnection | TenantDb): Promise<ReadonlyMap<string, ConfigStoredRow>>;
|
|
116
|
+
getCascade(qualifiedKey: string, keyDef: ConfigKeyDefinition, tenantId: TenantId, userId: string, db: DbConnection | TenantDb, secretsReader?: ConfigSecretsReader): Promise<ConfigCascade>;
|
|
117
|
+
getCascadeBatch(keys: readonly string[], keyDefs: ReadonlyMap<string, ConfigKeyDefinition>, tenantId: TenantId, userId: string, db: DbConnection | TenantDb, secretsReader?: ConfigSecretsReader): Promise<ReadonlyMap<string, ConfigCascade>>;
|
|
118
|
+
};
|
|
119
|
+
export type RunIn = "api" | "worker" | "both";
|
|
120
|
+
export type JobRunIn = Exclude<RunIn, "both">;
|
|
121
|
+
export type JobHandlerFn = (payload: Record<string, unknown>, context: JobContext) => Promise<void>;
|
|
122
|
+
export type JobTrigger = {
|
|
123
|
+
readonly on: import("./handlers.js").NameOrRef | readonly import("./handlers.js").NameOrRef[];
|
|
124
|
+
readonly where?: Readonly<Record<string, string | number | boolean>>;
|
|
125
|
+
} | {
|
|
126
|
+
readonly cron: string;
|
|
127
|
+
} | {
|
|
128
|
+
readonly manual: true;
|
|
129
|
+
};
|
|
130
|
+
export type JobBackoffStrategy = "fixed" | "exponential";
|
|
131
|
+
export type JobBackoff = JobBackoffStrategy | {
|
|
132
|
+
readonly type: JobBackoffStrategy;
|
|
133
|
+
readonly delayMs?: number | undefined;
|
|
134
|
+
};
|
|
135
|
+
export type JobDefinition = {
|
|
136
|
+
readonly name: string;
|
|
137
|
+
readonly handler: JobHandlerFn;
|
|
138
|
+
readonly trigger: JobTrigger;
|
|
139
|
+
readonly concurrency?: ConcurrencyMode | undefined;
|
|
140
|
+
readonly maxPerTenant?: number | undefined;
|
|
141
|
+
readonly debounceMs?: number | undefined;
|
|
142
|
+
readonly retries?: number | undefined;
|
|
143
|
+
readonly backoff?: JobBackoff | undefined;
|
|
144
|
+
readonly timeout?: number | undefined;
|
|
145
|
+
readonly schema?: ZodType | undefined;
|
|
146
|
+
readonly runOnBoot?: boolean | undefined;
|
|
147
|
+
readonly bootGate?: boolean | undefined;
|
|
148
|
+
readonly perTenant?: boolean | undefined;
|
|
149
|
+
readonly runIn?: JobRunIn | undefined;
|
|
150
|
+
readonly escapeHatch?: EscapeHatchDeclaration | undefined;
|
|
151
|
+
readonly tenantVisibleFailure?: {
|
|
152
|
+
readonly messageKey: string;
|
|
153
|
+
readonly subjectFields?: readonly string[] | undefined;
|
|
154
|
+
} | undefined;
|
|
155
|
+
};
|
|
156
|
+
export type NotificationRecipientFn = (result: import("./hooks.js").SaveContext) => string | readonly string[] | {
|
|
157
|
+
readonly tenant: string;
|
|
158
|
+
} | null;
|
|
159
|
+
export type NotificationDataFn = (result: import("./hooks.js").SaveContext) => Record<string, unknown>;
|
|
160
|
+
export type NotificationTemplateFn = (data: Record<string, unknown>) => Record<string, unknown>;
|
|
161
|
+
export type NotificationDefinition = {
|
|
162
|
+
readonly name: string;
|
|
163
|
+
readonly trigger: {
|
|
164
|
+
readonly on: string;
|
|
165
|
+
};
|
|
166
|
+
readonly recipient: NotificationRecipientFn;
|
|
167
|
+
readonly data: NotificationDataFn;
|
|
168
|
+
readonly templates: Readonly<Record<string, NotificationTemplateFn>> | undefined;
|
|
169
|
+
};
|
|
170
|
+
export type PluralForms = {
|
|
171
|
+
readonly zero?: string;
|
|
172
|
+
readonly one?: string;
|
|
173
|
+
readonly two?: string;
|
|
174
|
+
readonly few?: string;
|
|
175
|
+
readonly many?: string;
|
|
176
|
+
readonly other: string;
|
|
177
|
+
};
|
|
178
|
+
export type TranslationValue = string | PluralForms;
|
|
179
|
+
export type TranslationEntry = Readonly<Record<string, TranslationValue>>;
|
|
180
|
+
export type TranslationKeys = Readonly<Record<string, TranslationEntry>>;
|
|
181
|
+
export type TranslationsDef = {
|
|
182
|
+
readonly keys: TranslationKeys;
|
|
183
|
+
};
|
|
184
|
+
export type RegistrarExtensionHooks = {
|
|
185
|
+
readonly preSave?: PreSaveHookFn;
|
|
186
|
+
readonly postSave?: PostSaveHookFn;
|
|
187
|
+
readonly preDelete?: PreDeleteHookFn;
|
|
188
|
+
readonly postDelete?: PostDeleteHookFn;
|
|
189
|
+
readonly preQuery?: PreQueryHookFn;
|
|
190
|
+
};
|
|
191
|
+
export type UiExtensionDef = {
|
|
192
|
+
readonly editSection?: string;
|
|
193
|
+
readonly listColumns?: string;
|
|
194
|
+
readonly filters?: string;
|
|
195
|
+
};
|
|
196
|
+
export type RegistrarExtensionDef = {
|
|
197
|
+
readonly onRegister?: (entityName: string, options?: Record<string, unknown>) => void;
|
|
198
|
+
readonly extendSchema?: (entityName: string) => Record<string, FieldDefinition>;
|
|
199
|
+
readonly hooks?: RegistrarExtensionHooks;
|
|
200
|
+
readonly extendSearch?: (entityName: string) => Record<string, unknown>;
|
|
201
|
+
readonly uiExtension?: UiExtensionDef;
|
|
202
|
+
};
|
|
203
|
+
export type RegistrarExtensionRegistration = {
|
|
204
|
+
readonly extensionName: string;
|
|
205
|
+
readonly entityName: string;
|
|
206
|
+
readonly options?: Record<string, unknown> | undefined;
|
|
207
|
+
readonly featureName?: string;
|
|
208
|
+
};
|
|
209
|
+
export type ExtensionSelectorDef = {
|
|
210
|
+
readonly extensionName: string;
|
|
211
|
+
readonly qualifiedKey: string;
|
|
212
|
+
};
|
|
213
|
+
export type ReferenceDataDef = {
|
|
214
|
+
readonly entityName: string;
|
|
215
|
+
readonly data: readonly Record<string, unknown>[];
|
|
216
|
+
readonly upsertKey?: string | undefined;
|
|
217
|
+
};
|
|
218
|
+
export type ConfigSeedDef = {
|
|
219
|
+
readonly key: string;
|
|
220
|
+
readonly value: string | number | boolean;
|
|
221
|
+
readonly scope?: ConfigScope;
|
|
222
|
+
readonly tenantId?: string;
|
|
223
|
+
readonly userId?: string;
|
|
224
|
+
};
|
|
225
|
+
export type CreateSeedOptions = {
|
|
226
|
+
readonly value: string | number | boolean;
|
|
227
|
+
};
|
|
228
|
+
export type CreateTenantSeedOptions = {
|
|
229
|
+
readonly tenantId?: string;
|
|
230
|
+
};
|
|
231
|
+
export type CreateUserSeedOptions = {
|
|
232
|
+
readonly tenantId: string;
|
|
233
|
+
readonly userId: string;
|
|
234
|
+
};
|
package/dist/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityId, TenantId } from "./identifiers.js";
|
|
2
|
+
export type CursorQueryOptions = {
|
|
3
|
+
tenantId: TenantId;
|
|
4
|
+
cursor?: string;
|
|
5
|
+
limit?: number;
|
|
6
|
+
filterIds?: readonly EntityId[];
|
|
7
|
+
sort?: string;
|
|
8
|
+
sortDirection?: "asc" | "desc";
|
|
9
|
+
};
|
|
10
|
+
export type CursorResult<T> = {
|
|
11
|
+
rows: T[];
|
|
12
|
+
nextCursor: string | null;
|
|
13
|
+
/** Optional total row count — only present when the caller sets
|
|
14
|
+
* `totalCount: true` on the query. */
|
|
15
|
+
total?: number;
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type postgres from "postgres";
|
|
2
|
+
export type RawDbClient = {
|
|
3
|
+
unsafe: (...args: any[]) => any;
|
|
4
|
+
begin: (...args: any[]) => any;
|
|
5
|
+
end?: (options?: {
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
export type DbConnection = ReturnType<typeof postgres> | RawDbClient;
|
|
10
|
+
export type DbTx = postgres.TransactionSql<Record<string, unknown>> | RawDbClient;
|
|
11
|
+
export type DbRunner = DbConnection | DbTx;
|
|
12
|
+
export type DbRow = Record<string, unknown>;
|
|
13
|
+
export type PgClient = ReturnType<typeof postgres>;
|
|
14
|
+
export type PgListenClient = ReturnType<typeof postgres>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type * as z from "zod";
|
|
2
|
+
import type { ZodType } from "zod";
|
|
3
|
+
import type { KumikoEventTypeMap } from "./event-type-map.js";
|
|
4
|
+
import type { AccessRule, AgentHandlerHints, EscapeHatchDeclaration, HandlerContext, QueryEvent, RateLimitDeclaration, WriteEvent, WriteResult } from "./handlers.js";
|
|
5
|
+
import type { PipelineDef } from "./step.js";
|
|
6
|
+
export type WriteHandlerDefinition<TName extends string = string, TSchema extends ZodType = ZodType, TData = unknown, TMap extends object = KumikoEventTypeMap> = {
|
|
7
|
+
readonly name: TName;
|
|
8
|
+
readonly schema: TSchema;
|
|
9
|
+
readonly access: AccessRule;
|
|
10
|
+
readonly description?: string;
|
|
11
|
+
readonly agent?: AgentHandlerHints;
|
|
12
|
+
readonly unsafeSkipTransitionGuard?: boolean;
|
|
13
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
14
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
15
|
+
readonly handler: (event: WriteEvent<z.infer<TSchema>>, context: HandlerContext<TMap>) => Promise<WriteResult<TData>>;
|
|
16
|
+
readonly perform?: PipelineDef<z.infer<TSchema>, TData>;
|
|
17
|
+
};
|
|
18
|
+
export type WriteHandlerInput<TName extends string = string, TSchema extends ZodType = ZodType, TData = unknown, TMap extends object = KumikoEventTypeMap> = {
|
|
19
|
+
readonly name: TName;
|
|
20
|
+
readonly schema: TSchema;
|
|
21
|
+
readonly access: AccessRule;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
readonly agent?: AgentHandlerHints;
|
|
24
|
+
readonly unsafeSkipTransitionGuard?: boolean;
|
|
25
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
26
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
27
|
+
} & ({
|
|
28
|
+
readonly handler: (event: WriteEvent<z.infer<TSchema>>, context: HandlerContext<TMap>) => Promise<WriteResult<TData>>;
|
|
29
|
+
readonly perform?: never;
|
|
30
|
+
} | {
|
|
31
|
+
readonly perform: PipelineDef<z.infer<TSchema>, TData>;
|
|
32
|
+
readonly handler?: never;
|
|
33
|
+
});
|
|
34
|
+
export type QueryHandlerDefinition<TName extends string = string, TSchema extends ZodType = ZodType, TResult = unknown, TMap extends object = KumikoEventTypeMap> = {
|
|
35
|
+
readonly name: TName;
|
|
36
|
+
readonly schema: TSchema;
|
|
37
|
+
readonly access: AccessRule;
|
|
38
|
+
readonly description?: string;
|
|
39
|
+
readonly agent?: AgentHandlerHints;
|
|
40
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
41
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
42
|
+
readonly handler: (query: QueryEvent<z.infer<TSchema>>, context: HandlerContext<TMap>) => Promise<TResult>;
|
|
43
|
+
/** Zod schema of `handler`'s actual return value — see QueryHandlerDef's
|
|
44
|
+
* doc (handlers.ts) for the boot-validator checks this unlocks. Not
|
|
45
|
+
* inferred from `TResult`: TResult is a compile-time-only type param
|
|
46
|
+
* (this function never receives a runtime schema for it), so callers
|
|
47
|
+
* that want boot-time column checks declare `outputSchema` explicitly,
|
|
48
|
+
* same as `schema` for the input side. */
|
|
49
|
+
readonly outputSchema?: ZodType;
|
|
50
|
+
};
|
|
51
|
+
export type StreamHandlerDefinition<TName extends string = string, TSchema extends ZodType = ZodType, TChunk = unknown, TMap extends object = KumikoEventTypeMap> = {
|
|
52
|
+
readonly name: TName;
|
|
53
|
+
readonly schema: TSchema;
|
|
54
|
+
readonly access: AccessRule;
|
|
55
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
56
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
57
|
+
readonly handler: (query: QueryEvent<z.infer<TSchema>>, context: HandlerContext<TMap>) => AsyncGenerator<TChunk>;
|
|
58
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type VariantFit = "cover" | "inside" | "contain";
|
|
2
|
+
export type VariantFormat = "webp" | "avif" | "jpeg";
|
|
3
|
+
export type BlurRegion = {
|
|
4
|
+
readonly x: number;
|
|
5
|
+
readonly y: number;
|
|
6
|
+
readonly width: number;
|
|
7
|
+
readonly height: number;
|
|
8
|
+
};
|
|
9
|
+
export type OverlayGravity = "north-west" | "north-east" | "south-west" | "south-east" | "center";
|
|
10
|
+
type OverlayPlacement = {
|
|
11
|
+
readonly widthPct: number;
|
|
12
|
+
readonly gravity: OverlayGravity;
|
|
13
|
+
readonly marginPct?: number;
|
|
14
|
+
};
|
|
15
|
+
export type OverlayLayer = ({
|
|
16
|
+
readonly kind: "qr";
|
|
17
|
+
readonly dataToken: string;
|
|
18
|
+
} & OverlayPlacement) | ({
|
|
19
|
+
readonly kind: "image";
|
|
20
|
+
readonly imageBase64: string;
|
|
21
|
+
} & OverlayPlacement);
|
|
22
|
+
export type ResolvedOverlayLayer = ({
|
|
23
|
+
readonly kind: "qr";
|
|
24
|
+
readonly data: string;
|
|
25
|
+
} & OverlayPlacement) | Extract<OverlayLayer, {
|
|
26
|
+
kind: "image";
|
|
27
|
+
}>;
|
|
28
|
+
export type VariantSpec = {
|
|
29
|
+
readonly fit?: VariantFit;
|
|
30
|
+
readonly size?: {
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
};
|
|
34
|
+
readonly maxEdge?: number;
|
|
35
|
+
readonly format?: VariantFormat;
|
|
36
|
+
readonly quality?: number;
|
|
37
|
+
readonly blur?: number;
|
|
38
|
+
readonly blurRegions?: readonly BlurRegion[];
|
|
39
|
+
readonly overlays?: readonly OverlayLayer[];
|
|
40
|
+
readonly resolvedOverlays?: readonly ResolvedOverlayLayer[];
|
|
41
|
+
};
|
|
42
|
+
export type DerivativeRendererPlugin = {
|
|
43
|
+
readonly render: (input: Uint8Array, spec: VariantSpec, sourceMimeType: string) => Promise<Uint8Array>;
|
|
44
|
+
};
|
|
45
|
+
export type VariantResult = {
|
|
46
|
+
readonly storageKey: string;
|
|
47
|
+
readonly mimeType: string;
|
|
48
|
+
readonly rendered: boolean;
|
|
49
|
+
};
|
|
50
|
+
export type DerivativesContext = {
|
|
51
|
+
readonly variant: (fileRefId: string, spec: VariantSpec, name: string) => Promise<VariantResult>;
|
|
52
|
+
};
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityId, TenantId } from "./identifiers.js";
|
|
2
|
+
export type EntityCache = {
|
|
3
|
+
/** Get a single cached entity. Returns null on miss. */
|
|
4
|
+
get(tenantId: TenantId, entityName: string, id: EntityId): Promise<Record<string, unknown> | null>;
|
|
5
|
+
/** Get multiple cached entities. Returns a Map of id → data (misses are absent). */
|
|
6
|
+
mget(tenantId: TenantId, entityName: string, ids: readonly EntityId[]): Promise<Map<EntityId, Record<string, unknown>>>;
|
|
7
|
+
/** Cache a single entity. */
|
|
8
|
+
set(tenantId: TenantId, entityName: string, id: EntityId, data: Record<string, unknown>): Promise<void>;
|
|
9
|
+
/** Cache multiple entities at once. */
|
|
10
|
+
mset(tenantId: TenantId, entityName: string, entries: ReadonlyArray<{
|
|
11
|
+
id: EntityId;
|
|
12
|
+
data: Record<string, unknown>;
|
|
13
|
+
}>): Promise<void>;
|
|
14
|
+
/** Invalidate a single cached entity. */
|
|
15
|
+
del(tenantId: TenantId, entityName: string, id: EntityId): Promise<void>;
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EntityDefinition } from "./fields.js";
|
|
2
|
+
import type { AccessRule, AgentHandlerHints, EscapeHatchDeclaration, QueryHandlerDef, WriteHandlerDef } from "./handlers.js";
|
|
3
|
+
export type EntityHandlerOptions = {
|
|
4
|
+
readonly access: AccessRule;
|
|
5
|
+
readonly description?: string;
|
|
6
|
+
readonly agent?: AgentHandlerHints;
|
|
7
|
+
/** Lifts row filtering for this ONE handler across every tenant instead of
|
|
8
|
+
* the caller's own — for a SystemAdmin-only operator handler over an
|
|
9
|
+
* otherwise tenant-scoped entity. Every use reports an
|
|
10
|
+
* `acknowledge-cross-tenant` escape-hatch audit event. On write handlers
|
|
11
|
+
* update/delete/restore address the target row's own tenant stream.
|
|
12
|
+
* `access` stays the only caller gate. Unlike `escapeHatch` on a
|
|
13
|
+
* hand-written handler this does NOT grant `ctx.db.unsafeRaw`,
|
|
14
|
+
* `db.global()` writes or identity switches. */
|
|
15
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
16
|
+
/** @deprecated Use `escapeHatch: { reason }` — removed in a future release;
|
|
17
|
+
* run `scripts/codemod/migrate-cross-tenant.ts`. */
|
|
18
|
+
readonly crossTenant?: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** Options for the generic create/update handlers. */
|
|
21
|
+
export type EntityWriteHandlerOptions = EntityHandlerOptions & {
|
|
22
|
+
/** Fields this handler never writes. They leave the payload schema as
|
|
23
|
+
* "must be absent": a payload that still carries one fails validation
|
|
24
|
+
* instead of being stripped silently. create rejects a required field
|
|
25
|
+
* without default here, since the row could never be created. */
|
|
26
|
+
readonly excludeFields?: readonly string[];
|
|
27
|
+
};
|
|
28
|
+
export type EntityQueryHandlerOptions = EntityHandlerOptions;
|
|
29
|
+
export type EntityCrudVerb = "create" | "update" | "delete" | "restore" | "list" | "detail";
|
|
30
|
+
export type EntityCrudHandlerDefaults = Omit<EntityHandlerOptions, "access"> & {
|
|
31
|
+
readonly access?: AccessRule;
|
|
32
|
+
};
|
|
33
|
+
export type RegisterEntityCrudOptions = {
|
|
34
|
+
readonly write?: EntityCrudHandlerDefaults;
|
|
35
|
+
readonly read?: EntityCrudHandlerDefaults;
|
|
36
|
+
readonly verbs?: Partial<Record<EntityCrudVerb, boolean>>;
|
|
37
|
+
/** Per-verb access override — falls back to `write.access`/`read.access` when unset for a verb. */
|
|
38
|
+
readonly verbAccess?: Partial<Record<EntityCrudVerb, AccessRule>>;
|
|
39
|
+
/** Per-verb `description` — the author writes one sentence per verb; the AI-agent
|
|
40
|
+
* manifest exposes only the verbs described here (fail-closed, same rule as
|
|
41
|
+
* hand-written handlers). Falls back to `write.description`/`read.description`. */
|
|
42
|
+
readonly descriptions?: Partial<Record<EntityCrudVerb, string>>;
|
|
43
|
+
/** Per-verb `excludeFields` for the generic create/update handlers — see
|
|
44
|
+
* EntityWriteHandlerOptions. */
|
|
45
|
+
readonly excludeFields?: Partial<Record<"create" | "update", readonly string[]>>;
|
|
46
|
+
/** Default true. Set false when the entity was already registered (e.g. before r.relation). */
|
|
47
|
+
readonly registerEntity?: boolean;
|
|
48
|
+
};
|
|
49
|
+
/** Minimal registrar surface — keeps entity-handlers free of define-feature imports. */
|
|
50
|
+
export type EntityCrudRegistrar = {
|
|
51
|
+
entity(name: string, definition: EntityDefinition): unknown;
|
|
52
|
+
writeHandler(def: WriteHandlerDef): unknown;
|
|
53
|
+
queryHandler(def: QueryHandlerDef): unknown;
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EntityRelations } from "./relations.js";
|
|
2
|
+
import type { EntityTenancy } from "./tenancy-brand.js";
|
|
3
|
+
export type PgType = "uuid" | "text" | "boolean" | "integer" | "double precision" | "bigint" | "serial" | "bigserial" | "jsonb" | "timestamptz" | "timestamptz(3)" | "date" | `numeric(${number},${number})`;
|
|
4
|
+
export type ColumnMeta = {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly pgType: PgType;
|
|
7
|
+
readonly notNull: boolean;
|
|
8
|
+
readonly defaultSql?: string;
|
|
9
|
+
readonly primaryKey?: boolean;
|
|
10
|
+
readonly identity?: boolean;
|
|
11
|
+
readonly bigintJsMode?: "number" | "bigint";
|
|
12
|
+
};
|
|
13
|
+
export type IndexMeta = {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly columns: readonly string[];
|
|
16
|
+
readonly unique?: boolean;
|
|
17
|
+
readonly whereSql?: string;
|
|
18
|
+
readonly needsManualWhere?: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type CompositePrimaryKeyMeta = {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly columns: readonly string[];
|
|
23
|
+
};
|
|
24
|
+
export type EntityTableMeta = {
|
|
25
|
+
readonly tableName: string;
|
|
26
|
+
readonly columns: readonly ColumnMeta[];
|
|
27
|
+
readonly indexes: readonly IndexMeta[];
|
|
28
|
+
readonly compositePrimaryKey?: CompositePrimaryKeyMeta;
|
|
29
|
+
readonly source: "managed" | "unmanaged";
|
|
30
|
+
readonly piiSubjectFields?: readonly string[];
|
|
31
|
+
readonly tenancy?: "global";
|
|
32
|
+
};
|
|
33
|
+
export type BuildEntityTableMetaOptions = {
|
|
34
|
+
readonly featureName?: string;
|
|
35
|
+
readonly relations?: EntityRelations;
|
|
36
|
+
readonly source?: EntityTableMeta["source"];
|
|
37
|
+
};
|
|
38
|
+
export type UnmanagedTableInput = {
|
|
39
|
+
readonly tableName: string;
|
|
40
|
+
readonly columns: readonly ColumnMeta[];
|
|
41
|
+
readonly indexes?: readonly IndexMeta[];
|
|
42
|
+
readonly compositePrimaryKey?: CompositePrimaryKeyMeta;
|
|
43
|
+
readonly tenancy?: EntityTenancy;
|
|
44
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Plain-data types for EntityTableMeta — split from the runtime
|
|
2
|
+
// (deriveEntityTableMeta, resolveTableName, defineUnmanagedTable) in
|
|
3
|
+
// entity-table-meta.ts. Prep step for the types-only package extraction
|
|
4
|
+
// (#1283) — this file must have ONLY `import type`, no value imports
|
|
5
|
+
// (crypto/DB deps).
|
|
6
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|