@ai-matrx/alchemy 0.8.59 → 0.9.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/CHANGELOG.md +36 -0
- package/README.md +2 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.cjs.map +1 -1
- package/dist/actions.d.cts +300 -3
- package/dist/actions.d.ts +300 -3
- package/dist/actions.js +1 -1
- package/dist/actions.js.map +1 -1
- package/dist/checks.cjs +1 -1
- package/dist/checks.cjs.map +1 -1
- package/dist/checks.d.cts +22 -1
- package/dist/checks.d.ts +22 -1
- package/dist/checks.js +2 -2
- package/dist/checks.js.map +1 -1
- package/dist/core.d.cts +141 -26
- package/dist/core.d.ts +141 -26
- package/dist/declare.cjs +1 -1
- package/dist/declare.cjs.map +1 -1
- package/dist/declare.d.cts +12 -4
- package/dist/declare.d.ts +12 -4
- package/dist/declare.js +1 -1
- package/dist/declare.js.map +1 -1
- package/dist/index.d.cts +141 -26
- package/dist/index.d.ts +141 -26
- package/dist/menu.cjs +1 -1
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.d.cts +109 -2
- package/dist/menu.d.ts +109 -2
- package/dist/menu.js +1 -1
- package/dist/menu.js.map +1 -1
- package/dist/operate-server.d.cts +6 -0
- package/dist/operate-server.d.ts +6 -0
- package/dist/operate.d.cts +141 -26
- package/dist/operate.d.ts +141 -26
- package/dist/ports.cjs.map +1 -1
- package/dist/ports.d.cts +116 -1
- package/dist/ports.d.ts +116 -1
- package/dist/react-bar.cjs +2 -2
- package/dist/react-bar.cjs.map +1 -1
- package/dist/react-bar.d.cts +4 -2
- package/dist/react-bar.d.ts +4 -2
- package/dist/react-bar.js +2 -2
- package/dist/react-bar.js.map +1 -1
- package/dist/react-host.d.cts +124 -3
- package/dist/react-host.d.ts +124 -3
- package/dist/react-menu.cjs +2 -2
- package/dist/react-menu.cjs.map +1 -1
- package/dist/react-menu.d.cts +20 -4
- package/dist/react-menu.d.ts +20 -4
- package/dist/react-menu.js +2 -2
- package/dist/react-menu.js.map +1 -1
- package/dist/react-overflow.cjs +2 -2
- package/dist/react-overflow.cjs.map +1 -1
- package/dist/react-overflow.d.cts +109 -2
- package/dist/react-overflow.d.ts +109 -2
- package/dist/react-overflow.js +2 -2
- package/dist/react-overflow.js.map +1 -1
- package/dist/react-palette.cjs +1 -1
- package/dist/react-palette.cjs.map +1 -1
- package/dist/react-palette.d.cts +4 -2
- package/dist/react-palette.d.ts +4 -2
- package/dist/react-palette.js +1 -1
- package/dist/react-palette.js.map +1 -1
- package/dist/react-selection.cjs +2 -2
- package/dist/react-selection.cjs.map +1 -1
- package/dist/react-selection.d.cts +4 -2
- package/dist/react-selection.d.ts +4 -2
- package/dist/react-selection.js +2 -2
- package/dist/react-selection.js.map +1 -1
- package/dist/react-sheet.cjs +2 -2
- package/dist/react-sheet.cjs.map +1 -1
- package/dist/react-sheet.d.cts +4 -2
- package/dist/react-sheet.d.ts +4 -2
- package/dist/react-sheet.js +2 -2
- package/dist/react-sheet.js.map +1 -1
- package/package.json +3 -3
package/dist/core.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Framework-neutral transfer contracts (Alchemy Operate, CONTRACT §2.3). All data crossing this boundary is JSON.
|
|
3
3
|
* Moved from `@ai-matrx/kit/content-transfer` in ALC-16; the format-adapter contract lives in `./contract`.
|
|
4
4
|
*/
|
|
5
|
-
type Json$
|
|
6
|
-
[key: string]: Json$
|
|
5
|
+
type Json$2 = null | boolean | number | string | Json$2[] | {
|
|
6
|
+
[key: string]: Json$2;
|
|
7
7
|
};
|
|
8
8
|
type Payload =
|
|
9
9
|
/** A text payload may name its language (code blocks): downloads take its extension, Markdown fences it. */
|
|
@@ -16,15 +16,15 @@ type Payload =
|
|
|
16
16
|
text: string;
|
|
17
17
|
} | {
|
|
18
18
|
kind: "json";
|
|
19
|
-
value: Json$
|
|
19
|
+
value: Json$2;
|
|
20
20
|
} | {
|
|
21
21
|
kind: "rows";
|
|
22
|
-
rows: Record<string, Json$
|
|
22
|
+
rows: Record<string, Json$2>[];
|
|
23
23
|
columns: Column[];
|
|
24
24
|
} | {
|
|
25
25
|
kind: "registered";
|
|
26
26
|
format: string;
|
|
27
|
-
value: Json$
|
|
27
|
+
value: Json$2;
|
|
28
28
|
};
|
|
29
29
|
type Column = {
|
|
30
30
|
id: string;
|
|
@@ -38,9 +38,9 @@ type Column = {
|
|
|
38
38
|
dataType?: string;
|
|
39
39
|
order?: number;
|
|
40
40
|
required?: boolean;
|
|
41
|
-
defaultValue?: Json$
|
|
42
|
-
validation?: Json$
|
|
43
|
-
metadata?: Json$
|
|
41
|
+
defaultValue?: Json$2;
|
|
42
|
+
validation?: Json$2;
|
|
43
|
+
metadata?: Json$2;
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
46
|
type ExportProjection = {
|
|
@@ -93,21 +93,21 @@ type Snapshot = RawSnapshot & {
|
|
|
93
93
|
type QuerySnapshot = {
|
|
94
94
|
sourceId: string;
|
|
95
95
|
revision: string;
|
|
96
|
-
query: Json$
|
|
96
|
+
query: Json$2;
|
|
97
97
|
order: {
|
|
98
98
|
field: string;
|
|
99
99
|
direction: "asc" | "desc";
|
|
100
100
|
}[];
|
|
101
101
|
};
|
|
102
102
|
type ExportPage = {
|
|
103
|
-
rows: Record<string, Json$
|
|
103
|
+
rows: Record<string, Json$2>[];
|
|
104
104
|
nextCursor: string | null;
|
|
105
105
|
coverage: Coverage;
|
|
106
106
|
consistencyToken: string | null;
|
|
107
107
|
};
|
|
108
108
|
type CapturedAllMatching = {
|
|
109
109
|
query: QuerySnapshot;
|
|
110
|
-
getRowId(row: Record<string, Json$
|
|
110
|
+
getRowId(row: Record<string, Json$2>): string;
|
|
111
111
|
page(request: {
|
|
112
112
|
query: QuerySnapshot;
|
|
113
113
|
cursor: string | null;
|
|
@@ -147,7 +147,7 @@ type Draft = {
|
|
|
147
147
|
};
|
|
148
148
|
type Transform = {
|
|
149
149
|
id: string;
|
|
150
|
-
apply(draft: Draft, options: Json$
|
|
150
|
+
apply(draft: Draft, options: Json$2, signal: AbortSignal): Promise<Draft>;
|
|
151
151
|
};
|
|
152
152
|
type Artifact = {
|
|
153
153
|
snapshotId: string;
|
|
@@ -338,9 +338,9 @@ type BoundAllMatching = {
|
|
|
338
338
|
type NormalizeTransferJsonOptions = {
|
|
339
339
|
omitUndefinedObjectProperties?: boolean;
|
|
340
340
|
};
|
|
341
|
-
declare function normalizeTransferJson(value: unknown, options?: NormalizeTransferJsonOptions): Json$
|
|
341
|
+
declare function normalizeTransferJson(value: unknown, options?: NormalizeTransferJsonOptions): Json$2;
|
|
342
342
|
/** Column ids are identities, never an alternative data address. */
|
|
343
|
-
declare function readTransferCell(row: Record<string, Json$
|
|
343
|
+
declare function readTransferCell(row: Record<string, Json$2>, column: Column): Json$2 | undefined;
|
|
344
344
|
declare function projectSnapshot(raw: RawSnapshot, projection: ExportProjection): Snapshot;
|
|
345
345
|
declare function directSource(payload: Payload, options?: Partial<Pick<RawSnapshot, "id" | "sourceId" | "revision" | "label" | "coverage" | "unsavedChanges" | "sections" | "limits"> & {
|
|
346
346
|
projection: ExportProjection;
|
|
@@ -385,7 +385,7 @@ declare function reduceJson(draft: Draft, options: {
|
|
|
385
385
|
maxArrayItems?: number | null;
|
|
386
386
|
}): Draft;
|
|
387
387
|
declare function collectAllMatching(c: BoundAllMatching, signal: AbortSignal): Promise<{
|
|
388
|
-
rows: Record<string, Json$
|
|
388
|
+
rows: Record<string, Json$2>[];
|
|
389
389
|
coverage: RawSnapshot["coverage"];
|
|
390
390
|
omissions: Omission[];
|
|
391
391
|
error?: ContentTransferError;
|
|
@@ -433,6 +433,16 @@ declare function createSurfaceTransferHandle(options: {
|
|
|
433
433
|
/** Applies explicit preparation/source limits with exact omissions; token target is advisory. */
|
|
434
434
|
declare function applyTransferLimits(draft: Draft, limits: Partial<TransferLimits>): Draft;
|
|
435
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Matrx Alchemy — Declare types (CONTRACT §2.1).
|
|
438
|
+
*
|
|
439
|
+
* A declaration is plain JSON data (chair ruling N2): no functions, no classes,
|
|
440
|
+
* no React. Runtime behaviour lives in `MountedSurface` (`/declare/host`) and in
|
|
441
|
+
* handler registrations, never here. Zero React, zero `@ai-matrx/agents`.
|
|
442
|
+
*/
|
|
443
|
+
type Json$1 = null | boolean | number | string | Json$1[] | {
|
|
444
|
+
[key: string]: Json$1;
|
|
445
|
+
};
|
|
436
446
|
/** Unchanged from `ui_surface_value_type_chk`. */
|
|
437
447
|
type ValueType = "string" | "number" | "boolean" | "object" | "array" | "document";
|
|
438
448
|
type Classification = "ordinary" | "secret" | "credential";
|
|
@@ -639,6 +649,75 @@ interface ClickTarget {
|
|
|
639
649
|
host?: unknown;
|
|
640
650
|
}
|
|
641
651
|
|
|
652
|
+
/**
|
|
653
|
+
* Surface Actions — the shapes (Applets CONTRACTS §6, FROZEN; exported here as a superset).
|
|
654
|
+
*
|
|
655
|
+
* An Action is one thing a surface can have done to it, by a person, an agent,
|
|
656
|
+
* an applet or an automation: a write target, a client tool, a Kind Action or a
|
|
657
|
+
* row in `ui.ui_surface_action`. All of them project onto `ActionDeclaration`
|
|
658
|
+
* (`./declarations.ts`) and run through ONE runner (`./surface-run.ts`). There is
|
|
659
|
+
* never a second registry: `name` IS the alchemy action id, and `category`
|
|
660
|
+
* defaults to "applet" in alchemy's closed `ActionCategory` union.
|
|
661
|
+
*
|
|
662
|
+
* Types only — no runtime code, no React, no `@ai-matrx/agents`. `/ports`
|
|
663
|
+
* imports from here, so this file imports nothing but local types.
|
|
664
|
+
*/
|
|
665
|
+
|
|
666
|
+
/** Who started a run. */
|
|
667
|
+
type ActionCaller = "person" | "agent" | "applet" | "automation";
|
|
668
|
+
/** Who may run it without a click: "manual" = only a person; "ask" = proposed first; "auto" = runs. */
|
|
669
|
+
type ActionPolicy = "ask" | "auto" | "manual";
|
|
670
|
+
interface ActionContext {
|
|
671
|
+
runId: string;
|
|
672
|
+
by: ActionCaller;
|
|
673
|
+
viewerId: string | null;
|
|
674
|
+
surfaceName?: string;
|
|
675
|
+
policy?: ActionPolicy;
|
|
676
|
+
}
|
|
677
|
+
/** The system's own sentence, never thrown into a UI. Superset of RecordsError (CONTRACTS §0 `AppletError`). */
|
|
678
|
+
interface ActionError {
|
|
679
|
+
code: string;
|
|
680
|
+
message: string;
|
|
681
|
+
retryable: boolean;
|
|
682
|
+
diagnostic?: string;
|
|
683
|
+
}
|
|
684
|
+
/** CONTRACTS §0 `Result<T>`. */
|
|
685
|
+
type ActionResult<T = unknown> = {
|
|
686
|
+
ok: true;
|
|
687
|
+
data: T;
|
|
688
|
+
} | {
|
|
689
|
+
ok: false;
|
|
690
|
+
error: ActionError;
|
|
691
|
+
};
|
|
692
|
+
/** `POST /actions/run` (aidream) — the request. */
|
|
693
|
+
interface ServerActionRunRequest {
|
|
694
|
+
name: string;
|
|
695
|
+
input: Json$1;
|
|
696
|
+
by: ActionCaller;
|
|
697
|
+
surface_name?: string;
|
|
698
|
+
policy?: ActionPolicy;
|
|
699
|
+
}
|
|
700
|
+
/** `POST /actions/run` (aidream) — the response. */
|
|
701
|
+
interface ServerActionRunResponse {
|
|
702
|
+
status: "applied" | "proposed" | "refused";
|
|
703
|
+
message: string;
|
|
704
|
+
receipts: Json$1[];
|
|
705
|
+
proposal?: Json$1;
|
|
706
|
+
}
|
|
707
|
+
/** A mandate run request: by alias (an Action's `target`) or by key. */
|
|
708
|
+
type MandateRunRequest = ({
|
|
709
|
+
alias: string;
|
|
710
|
+
key?: never;
|
|
711
|
+
} | {
|
|
712
|
+
key: string;
|
|
713
|
+
alias?: never;
|
|
714
|
+
}) & {
|
|
715
|
+
variables: Record<string, Json$1>;
|
|
716
|
+
userInput?: string;
|
|
717
|
+
by: ActionCaller;
|
|
718
|
+
policy: ActionPolicy;
|
|
719
|
+
};
|
|
720
|
+
|
|
642
721
|
/**
|
|
643
722
|
* `@ai-matrx/alchemy/ports` — the host ports (Matrx Alchemy CONTRACT §2.2).
|
|
644
723
|
*
|
|
@@ -687,6 +766,12 @@ interface ClickTarget {
|
|
|
687
766
|
* to an overlay carrying the session as data)
|
|
688
767
|
* transferKnobs absent → no organization default recipe; a person's own
|
|
689
768
|
* default (persistence) or the package's Full applies
|
|
769
|
+
* serverActions absent → `runs: "server"` Actions refuse with "not available here"
|
|
770
|
+
* mandates absent → `runs: "mandate"` Actions refuse the same way
|
|
771
|
+
* pageActions absent → `runs: "page"` Actions refuse the same way
|
|
772
|
+
* approvals absent → a policy "ask" Action started by an agent, applet or automation is refused
|
|
773
|
+
* ("needs a person's approval"); a person's own click is the approval
|
|
774
|
+
* (`runs: "navigate"` goes through `overlay.navigate`; overlay absent → refused)
|
|
690
775
|
*
|
|
691
776
|
* Types only: this entry has no runtime code.
|
|
692
777
|
*/
|
|
@@ -832,6 +917,36 @@ interface AlchemyHostPorts {
|
|
|
832
917
|
window?: WindowPort;
|
|
833
918
|
/** Organization default recipes, resolved by the host's Feature Knob ladder (platform → organization). */
|
|
834
919
|
transferKnobs?: TransferKnobsPort;
|
|
920
|
+
/** aidream `POST /actions/run`: a registered server action by name, as the caller, under the apply-policy cascade. */
|
|
921
|
+
serverActions?: ServerActionPort;
|
|
922
|
+
/** Runs a mandate by alias or key (the host binds `@ai-matrx/agents`; alchemy never imports it). */
|
|
923
|
+
mandates?: MandatePort;
|
|
924
|
+
/** The page's own handlers for `runs: "page"` Actions (in an applet frame: routed as `{ action, input, runId }`). */
|
|
925
|
+
pageActions?: PageActionPort;
|
|
926
|
+
/** Asks a person, in place, to approve an `ask` Action that an agent, applet or automation started. */
|
|
927
|
+
approvals?: ApprovalPort;
|
|
928
|
+
}
|
|
929
|
+
interface ServerActionPort {
|
|
930
|
+
run(request: ServerActionRunRequest): Promise<ServerActionRunResponse>;
|
|
931
|
+
}
|
|
932
|
+
interface MandatePort {
|
|
933
|
+
/** Resolves with the run's result (a kind envelope or JSON); rejects with the system's sentence. */
|
|
934
|
+
run(request: MandateRunRequest): Promise<unknown>;
|
|
935
|
+
}
|
|
936
|
+
interface ApprovalRequest {
|
|
937
|
+
action: string;
|
|
938
|
+
label: string;
|
|
939
|
+
description: string;
|
|
940
|
+
input: Json;
|
|
941
|
+
by: "agent" | "applet" | "automation";
|
|
942
|
+
surfaceName: string;
|
|
943
|
+
}
|
|
944
|
+
interface ApprovalPort {
|
|
945
|
+
/** Resolves true when the person approves; false when they decline or dismiss. */
|
|
946
|
+
ask(request: ApprovalRequest): Promise<boolean>;
|
|
947
|
+
}
|
|
948
|
+
interface PageActionPort {
|
|
949
|
+
dispatch(name: string, input: unknown, context: ActionContext): Promise<ActionResult<unknown>>;
|
|
835
950
|
}
|
|
836
951
|
/**
|
|
837
952
|
* Why a port and not `OverlayHostPort`: an overlay's `data` is `Json`, and a live preparation
|
|
@@ -983,7 +1098,7 @@ type TransferOperation = {
|
|
|
983
1098
|
} | {
|
|
984
1099
|
kind: "transform";
|
|
985
1100
|
transform: string;
|
|
986
|
-
options?: Json$
|
|
1101
|
+
options?: Json$2;
|
|
987
1102
|
} | {
|
|
988
1103
|
kind: "prepare-for-ai";
|
|
989
1104
|
instruction?: string;
|
|
@@ -1028,7 +1143,7 @@ interface ServerOperation {
|
|
|
1028
1143
|
statement: string;
|
|
1029
1144
|
supports(payload: Payload): boolean;
|
|
1030
1145
|
/** Projected draft only; sensitivity already applied. */
|
|
1031
|
-
toInput(draft: Draft): Json$
|
|
1146
|
+
toInput(draft: Draft): Json$2;
|
|
1032
1147
|
}
|
|
1033
1148
|
/** Delivery results: `copy` and `download` only ever deliver, degrade, cancel or fail (CONTRACT R16). */
|
|
1034
1149
|
type DeliveryOutcome = Extract<TransferOutcome, {
|
|
@@ -1110,7 +1225,7 @@ interface PreparationSession {
|
|
|
1110
1225
|
readonly snapshot: Snapshot;
|
|
1111
1226
|
readonly draft: Draft;
|
|
1112
1227
|
/** Deterministic transform, AI preparation or any registered transform — bumps draft.revision. */
|
|
1113
|
-
transform(id: string, options: Json$
|
|
1228
|
+
transform(id: string, options: Json$2, signal: AbortSignal): Promise<Draft>;
|
|
1114
1229
|
/** A manual edit. */
|
|
1115
1230
|
edit(payload: Payload): Draft;
|
|
1116
1231
|
/** Keep only these sections (ids from the snapshot). */
|
|
@@ -1228,19 +1343,19 @@ declare function patternBelow(pattern: string, pointer: string): boolean;
|
|
|
1228
1343
|
/** The path a person reads and copies: `/messages/*\/metadata` → `data.messages[*].metadata`. */
|
|
1229
1344
|
declare function displayPath(pointer: string, root?: string): string;
|
|
1230
1345
|
/** Exactly `JSON.stringify(value).length`, computed once per object (large sources stay cheap). */
|
|
1231
|
-
declare function jsonSize(value: Json$
|
|
1346
|
+
declare function jsonSize(value: Json$2): number;
|
|
1232
1347
|
/** The size a person expects for a node: a string's own length, else its JSON. */
|
|
1233
|
-
declare function nodeChars(value: Json$
|
|
1348
|
+
declare function nodeChars(value: Json$2): number;
|
|
1234
1349
|
/**
|
|
1235
1350
|
* The one-line stub that stands in for a node: its header (a string's first line, an object's
|
|
1236
1351
|
* short scalar members) and its original size.
|
|
1237
1352
|
*/
|
|
1238
|
-
declare function stubText(value: Json$
|
|
1353
|
+
declare function stubText(value: Json$2): string;
|
|
1239
1354
|
/** Every concrete pointer in `value` a pattern names (for counts, diffs and highlights). */
|
|
1240
|
-
declare function concretePointers(value: Json$
|
|
1355
|
+
declare function concretePointers(value: Json$2, pattern: string): string[];
|
|
1241
1356
|
/** Apply exclusions and per-node limits to a JSON value; returns the new value and what changed. */
|
|
1242
|
-
declare function applyStructureToJson(value: Json$
|
|
1243
|
-
value: Json$
|
|
1357
|
+
declare function applyStructureToJson(value: Json$2, recipe: StructureRecipe, labels?: Readonly<Record<string, string>>): {
|
|
1358
|
+
value: Json$2;
|
|
1244
1359
|
omissions: Omission[];
|
|
1245
1360
|
};
|
|
1246
1361
|
/** A JSON (or registered) draft with the person's structure choices applied. */
|
|
@@ -1250,7 +1365,7 @@ declare function applyJsonStructure(draft: Draft, recipe: StructureRecipe, label
|
|
|
1250
1365
|
* earlier sibling is excluded). Null when the node is excluded or cut; a stubbed ancestor answers
|
|
1251
1366
|
* with the stub's own pointer.
|
|
1252
1367
|
*/
|
|
1253
|
-
declare function outputPointer(value: Json$
|
|
1368
|
+
declare function outputPointer(value: Json$2, recipe: StructureRecipe, pointer: string): string | null;
|
|
1254
1369
|
declare function isProseSection(section: Section): boolean;
|
|
1255
1370
|
interface SectionLayout {
|
|
1256
1371
|
text: string;
|
|
@@ -1321,4 +1436,4 @@ declare function setPersonDefaultRecipe(ports: Pick<AlchemyHostPorts, "persisten
|
|
|
1321
1436
|
[key: string]: Json;
|
|
1322
1437
|
} | null): Promise<void>;
|
|
1323
1438
|
|
|
1324
|
-
export { type AgentPayloadEnvironment, type AgentPayloadInput, type AiPreparation, type Artifact, type BoundAllMatching, type BuiltInFormatId, type CapturedAllMatching, type CapturedSource, type Column, ContentTransferError, type Coverage, type Delivery, type DeliveryOutcome, type Draft, EMPTY_STRUCTURE, type ExportPage, type ExportProjection, FORMAT_ADAPTERS, type FormatAdapter, type FormatEngine, type FormatOptions, type Json$
|
|
1439
|
+
export { type AgentPayloadEnvironment, type AgentPayloadInput, type AiPreparation, type Artifact, type BoundAllMatching, type BuiltInFormatId, type CapturedAllMatching, type CapturedSource, type Column, ContentTransferError, type Coverage, type Delivery, type DeliveryOutcome, type Draft, EMPTY_STRUCTURE, type ExportPage, type ExportProjection, FORMAT_ADAPTERS, type FormatAdapter, type FormatEngine, type FormatOptions, type Json$2 as Json, type NodeLimit, type NormalizeTransferJsonOptions, type Notice, type Omission, type OutputSpan, type PageAction, type Payload, type PreparationOptions, type PreparationSession, type QuerySnapshot, type RawSnapshot, type Receipt, type RecipeOrigin, type ResolvedRecipe, type SealedArtifact, type Section, type SectionLayout, type ServerOperation, type Snapshot, type Source, type SpanMap, type StructureRecipe, type SurfaceHandle, TRANSFER_DEFAULT_RECIPE_SETTING, type TransferLimits, type TransferOperation, type TransferOutcome, type TransferPreferenceOverrides, type TransferPreferences, type TransferScope, type TransferSurfaceDeclaration, type TransferTarget, type Transform, type Transport, type WriteTargetRef, agentPayloadWithSpans, applyJsonStructure, applySectionSelection, applySectionStructure, applyStructureToJson, applyTransferLimits, assembleAgentPayload, buildAgentPayload, capture, collectAllMatching, concretePointers, createBrowserTransport, createDelivery, createDraft, createSurfaceTransferHandle, deriveDraft, directSource, displayPath, editDraft, eligibleFormats, exportedColumns, extensionForLanguage, fenceJsonBlock, formatAdapter, isProseSection, isSealed, joinPointer, jsonSize, jsonTextSpans, nodeChars, normalizeTransferJson, offsetSpans, openPreparation, outputPointer, patternBelow, patternCovers, patternMatches, pointerSegments, projectSnapshot, readTransferCell, recipeKey, reduceJson, refreshDraft, resetDraft, resolveDefaultRecipe, resolveTransferPreferences, resolveTransferRegistry, sealArtifact, sealDraft, sealTransferArtifact, sectionLayout, serialize, setPersonDefaultRecipe, sourceChanged, spanMap, stubText, transformRows, undoDraft };
|
package/dist/declare.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var declare_exports={};__export(declare_exports,{APPLY_POLICIES:()=>APPLY_POLICIES,BASELINE_GROUP_ORDER:()=>BASELINE_GROUP_ORDER,CLASSIFICATIONS:()=>CLASSIFICATIONS,DECLARATION_NAME_RE:()=>DECLARATION_NAME_RE,DEFAULT_MAX_INHERITANCE_DEPTH:()=>DEFAULT_MAX_INHERITANCE_DEPTH,DEFAULT_SENSITIVITY:()=>DEFAULT_SENSITIVITY,EXECUTION_MODES:()=>EXECUTION_MODES,GENERAL_GROUP_ORDER:()=>GENERAL_GROUP_ORDER,INHERITED_GROUP_ORDER_BASE:()=>INHERITED_GROUP_ORDER_BASE,LIVE_SLOTS:()=>LIVE_SLOTS,QUALIFIED_VALUE_KEY_RE:()=>QUALIFIED_VALUE_KEY_RE,READINESS:()=>READINESS,RESERVED_GROUP_KEYS:()=>RESERVED_GROUP_KEYS,STREAM_OPS:()=>STREAM_OPS,SURFACE_NAME_RE:()=>SURFACE_NAME_RE,VALUE_TYPES:()=>VALUE_TYPES,WRITE_MODES:()=>WRITE_MODES,canonicalJson:()=>canonicalJson,createDeclarationRegistry:()=>createDeclarationRegistry,declarationHash:()=>declarationHash,findOrphanRows:()=>findOrphanRows,parseQualifiedValueKey:()=>parseQualifiedValueKey,qualifyValueKey:()=>qualifyValueKey,resolveSensitivity:()=>resolveSensitivity,sha256Hex:()=>sha256Hex,surfaceClientOf:()=>surfaceClientOf,validateDeclarations:()=>validateDeclarations,validateLoadedValues:()=>validateLoadedValues});module.exports=__toCommonJS(declare_exports);var DECLARATION_NAME_RE=/^[a-z][a-z0-9_]*$/,SURFACE_NAME_RE=/^[a-z][a-z0-9-]*\/[a-z0-9-/]+$/,QUALIFIED_VALUE_KEY_RE=/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)?$/;function parseQualifiedValueKey(key){if(!QUALIFIED_VALUE_KEY_RE.test(key))return null;let dot=key.indexOf(".");return dot===-1?{itemType:"",name:key}:{itemType:key.slice(0,dot),name:key.slice(dot+1)}}function qualifyValueKey(itemType,name){return itemType?`${itemType}.${name}`:name}function surfaceClientOf(surfaceName){return surfaceName.split("/")[0]??""}function canonicalJson(value){if(value===void 0)return"null";if(value===null||typeof value!="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(entry=>canonicalJson(entry)).join(",")}]`;let record=value;return`{${Object.keys(record).filter(key=>record[key]!==void 0).sort().map(key=>`${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`}var K=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function sha256Hex(input){let bytes=new TextEncoder().encode(input),bitLength=bytes.length*8,padded=new Uint8Array(bytes.length+9+63>>6<<6);padded.set(bytes),padded[bytes.length]=128;let view=new DataView(padded.buffer);view.setUint32(padded.length-8,Math.floor(bitLength/4294967296)),view.setUint32(padded.length-4,bitLength>>>0);let h=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),w=new Uint32Array(64);for(let offset=0;offset<padded.length;offset+=64){for(let i=0;i<16;i+=1)w[i]=view.getUint32(offset+i*4);for(let i=16;i<64;i+=1){let a2=w[i-15],b2=w[i-2],s0=(a2>>>7|a2<<25)^(a2>>>18|a2<<14)^a2>>>3,s1=(b2>>>17|b2<<15)^(b2>>>19|b2<<13)^b2>>>10;w[i]=w[i-16]+s0+w[i-7]+s1>>>0}let a=h[0],b=h[1],c=h[2],d=h[3],e=h[4],f=h[5],g=h[6],hh=h[7];for(let i=0;i<64;i+=1){let S1=(e>>>6|e<<26)^(e>>>11|e<<21)^(e>>>25|e<<7),ch=e&f^~e&g,t1=hh+S1+ch+K[i]+w[i]>>>0,S0=(a>>>2|a<<30)^(a>>>13|a<<19)^(a>>>22|a<<10),maj=a&b^a&c^b&c,t2=S0+maj>>>0;hh=g,g=f,f=e,e=d+t1>>>0,d=c,c=b,b=a,a=t1+t2>>>0}h[0]=h[0]+a>>>0,h[1]=h[1]+b>>>0,h[2]=h[2]+c>>>0,h[3]=h[3]+d>>>0,h[4]=h[4]+e>>>0,h[5]=h[5]+f>>>0,h[6]=h[6]+g>>>0,h[7]=h[7]+hh>>>0}return Array.from(h,word=>word.toString(16).padStart(8,"0")).join("")}function declarationHash(declaration){return sha256Hex(canonicalJson(declaration))}var VALUE_TYPES=["string","number","boolean","object","array","document"],WRITE_MODES=["draft","entity","ui","stream"],APPLY_POLICIES=["manual","ask","auto","queued"],STREAM_OPS=["replace","insert_before","insert_after","prepend","append","patch"],EXECUTION_MODES=["python-stream","nextjs-stream","browser-realtime","local-runtime"],READINESS=["verified","partial","stub"],LIVE_SLOTS=["selection","on-demand","errors","requests"],CLASSIFICATIONS=["ordinary","secret","credential"],STRUCTURED=new Set(["object","array"]);function has(list,value){return typeof value=="string"&&list.includes(value)}function validateDeclarations(declarations,options={}){let issues=[],seenSurfaces=new Set,labelsByClient=new Map;for(let d of declarations){let s=d.surfaceName,push=(path,sentence,remedy,severity)=>issues.push({surfaceName:s,path,sentence,remedy,...severity?{severity}:{}});seenSurfaces.has(s)&&push("surfaceName",`Duplicate manifest surfaceName: "${s}" appears more than once.`,"Keep one declaration per surface."),seenSurfaces.add(s),SURFACE_NAME_RE.test(s)||push("surfaceName",`Surface "${s}" doesn't match the "<client>/<local>" convention.`,"Rename it to <client>/<local>.");let prefix=surfaceClientOf(s);d.client!==prefix&&push("client",`Surface "${s}" declares client "${String(d.client)}" but its name prefix is "${prefix}" \u2014 they must match.`,`Set client: "${prefix}".`),has(EXECUTION_MODES,d.executionMode)||push("executionMode",`Surface "${s}" has invalid executionMode "${String(d.executionMode)}".`,`Use one of ${EXECUTION_MODES.join(" | ")}.`),typeof d.description!="string"&&push("description",`Surface "${s}" has no description.`,'Add one sentence on what the surface is ("" only where the live row is empty).');let label=d.label?.trim();if(!label)push("label",`Surface "${s}" has no canonical label \u2014 label is required.`,"Add the ONE canonical human display name.");else{let clientLabels=labelsByClient.get(prefix)??new Map,clash=clientLabels.get(label.toLowerCase());clash&&clash!==s&&push("label",`Canonical label "${label}" is used by both "${clash}" and "${s}" \u2014 labels must be unique per client.`,"Give one of them a distinct label."),clientLabels.set(label.toLowerCase(),s),labelsByClient.set(prefix,clientLabels)}has(READINESS,d.readiness)?d.readiness!=="verified"&&!d.readinessNote?.trim()&&push("readinessNote",`Surface "${s}" is readiness "${d.readiness}" but has no readinessNote \u2014 say what's missing.`,"Add a one-line readinessNote."):push("readiness",`Surface "${s}" has invalid readiness "${String(d.readiness)}" (expected verified | partial | stub).`,"Set a valid readiness.");let groupKeys=new Set;for(let g of d.groups??[])groupKeys.add(g.key),!(g.key==="general"||g.key==="baseline"||g.key.startsWith("inherited:"))&&(DECLARATION_NAME_RE.test(g.key)||push(`groups/${g.key}`,`Surface "${s}" group "${g.key}" doesn't match /^[a-z][a-z0-9_]*$/.`,"Rename the group key to lower_snake_case."),(g.sortOrder<0||g.sortOrder>899)&&push(`groups/${g.key}/sortOrder`,`Surface "${s}" group "${g.key}" sortOrder ${g.sortOrder} is outside the curated band 0\u2013899.`,"Use a sortOrder between 0 and 899."),g.label?.trim()||push(`groups/${g.key}/label`,`Surface "${s}" group "${g.key}" has no canonical label.`,"Add a label."));let seenNamespaces=new Set;for(let ns of d.configNamespaces??[])seenNamespaces.has(ns.namespace)&&push(`configNamespaces/${ns.namespace}`,`Surface "${s}" declares duplicate config namespace "${ns.namespace}".`,"Remove the duplicate."),seenNamespaces.add(ns.namespace),options.knownNamespaces&&!options.knownNamespaces.has(ns.namespace)&&push(`configNamespaces/${ns.namespace}`,`Surface "${s}" references config namespace "${ns.namespace}" which is not registered.`,"Register the namespace first, or remove the reference.");if(d.values.length===0){push("values",`Surface "${s}" declares no values.`,"Declare at least one value.");continue}let seenValues=new Set;for(let v of d.values){let at=`values/${v.name}`;seenValues.has(v.name)&&push(at,`Surface "${s}" declares duplicate value "${v.name}".`,"Remove the duplicate."),seenValues.add(v.name),DECLARATION_NAME_RE.test(v.name)||push(at,`Surface "${s}" value "${v.name}" doesn't match /^[a-z][a-z0-9_]*$/ \u2014 the DB CHECK constraint will reject this.`,"Rename it to lower_snake_case."),has(VALUE_TYPES,v.valueType)||push(`${at}/valueType`,`Surface "${s}" value "${v.name}" has invalid valueType "${String(v.valueType)}".`,`Use one of ${VALUE_TYPES.join(" | ")}.`),(typeof v.typicalCharCount!="number"||v.typicalCharCount<0)&&push(`${at}/typicalCharCount`,`Surface "${s}" value "${v.name}" has invalid typicalCharCount.`,"Use a non-negative number."),v.sortOrder!==void 0&&(typeof v.sortOrder!="number"||v.sortOrder<0)&&push(`${at}/sortOrder`,`Surface "${s}" value "${v.name}" has invalid sortOrder.`,"Use a non-negative number."),v.groupKey&&!groupKeys.has(v.groupKey)&&push(`${at}/group`,`Surface "${s}" value "${v.name}" resolved to groupKey "${v.groupKey}" which is missing from the resolved groups list \u2014 registry group synthesis is broken.`,"Fix the registry resolution."),v.liveSlot!==void 0&&!has(LIVE_SLOTS,v.liveSlot)&&push(`${at}/liveSlot`,`Surface "${s}" value "${v.name}" has invalid liveSlot "${String(v.liveSlot)}".`,`Use one of ${LIVE_SLOTS.join(" | ")}.`),v.role!==void 0&&v.role!=="data"&&v.role!=="request"&&push(`${at}/role`,`Surface "${s}" value "${v.name}" has invalid role "${String(v.role)}".`,"Use data | request."),v.sensitivity?.classification!==void 0&&!has(CLASSIFICATIONS,v.sensitivity.classification)&&push(`${at}/sensitivity/classification`,`Surface "${s}" value "${v.name}" has invalid classification "${String(v.sensitivity.classification)}".`,`Use one of ${CLASSIFICATIONS.join(" | ")}.`)}for(let slot of d.liveSlots??[])has(LIVE_SLOTS,slot)||push("liveSlots",`Surface "${s}" declares unknown live slot "${String(slot)}".`,`Use one of ${LIVE_SLOTS.join(" | ")}.`);let itemTypeNames=new Set;for(let item of d.itemTypes??[]){let at=`itemTypes/${item.name}`;itemTypeNames.has(item.name)&&push(at,`Surface "${s}" declares duplicate item type "${item.name}".`,"Remove the duplicate."),itemTypeNames.add(item.name),DECLARATION_NAME_RE.test(item.name)||push(at,`Surface "${s}" item type "${item.name}" doesn't match /^[a-z][a-z0-9_]*$/.`,"Rename it to lower_snake_case."),(!item.label?.trim()||!item.description?.trim())&&push(at,`Surface "${s}" item type "${item.name}" needs a label and a description.`,"Add both.");let itemValues=new Set(item.values.map(v=>v.name));item.identity.length===0&&push(`${at}/identity`,`Surface "${s}" item type "${item.name}" has an empty identity.`,"Name the value(s) that identify one item.");for(let key of item.identity)itemValues.has(key)||push(`${at}/identity`,`Surface "${s}" item type "${item.name}" identity names "${key}", which is not one of its values.`,"Declare it as an item value.");for(let t of item.writeTargets??[])t.updatesValue&&!itemValues.has(t.updatesValue)&&push(`${at}/writeTargets/${t.name}`,`Surface "${s}" item type "${item.name}" write target "${t.name}" updatesValue "${t.updatesValue}" which is not an item value.`,"Point it at a declared item value.")}let seenTargets=new Set,structuredWithoutKind=[];for(let w of d.writeTargets??[]){let at=`writeTargets/${w.name}`;seenTargets.has(w.name)&&push(at,`Surface "${s}" declares duplicate write target "${w.name}".`,"Remove the duplicate."),seenTargets.add(w.name),DECLARATION_NAME_RE.test(w.name)||push(at,`Surface "${s}" write target "${w.name}" doesn't match /^[a-z][a-z0-9_]*$/.`,"Rename it to lower_snake_case."),(!w.label?.trim()||!w.description?.trim())&&push(at,`Surface "${s}" write target "${w.name}" needs a label and a description.`,"Add both."),has(VALUE_TYPES,w.valueType)||push(`${at}/valueType`,`Surface "${s}" write target "${w.name}" has invalid valueType "${String(w.valueType)}".`,`Use one of ${VALUE_TYPES.join(" | ")}.`),has(WRITE_MODES,w.mode)||push(`${at}/mode`,`Surface "${s}" write target "${w.name}" has invalid mode "${String(w.mode)}".`,`Use one of ${WRITE_MODES.join(" | ")}.`),w.applyPolicy!==void 0&&!has(APPLY_POLICIES,w.applyPolicy)&&push(`${at}/applyPolicy`,`Surface "${s}" write target "${w.name}" has invalid applyPolicy "${String(w.applyPolicy)}".`,`Use one of ${APPLY_POLICIES.join(" | ")}.`),w.itemType!==void 0&&!itemTypeNames.has(w.itemType)&&push(`${at}/itemType`,`Surface "${s}" write target "${w.name}" names item type "${w.itemType}", which the surface does not declare.`,"Declare the item type or drop itemType.");let readTwinDeclared=w.updatesValue?seenValues.has(w.updatesValue):!1;w.updatesValue&&!w.itemType&&!readTwinDeclared&&push(`${at}/updatesValue`,`Surface "${s}" write target "${w.name}" updatesValue "${w.updatesValue}" which is not a declared value.`,"Point updatesValue at a declared value."),w.patchable&&!w.updatesValue&&push(`${at}/patchable`,`Surface "${s}" write target "${w.name}" is patchable but declares no updatesValue \u2014 an anchored edit has nothing to read.`,"Declare the read twin in updatesValue."),w.patchable&&w.valueType!=="string"&&w.valueType!=="document"&&push(`${at}/patchable`,`Surface "${s}" write target "${w.name}" is patchable but valueType is "${w.valueType}" (patching is for "string" | "document").`,"Drop patchable or change the value type."),w.mode==="stream"?((!w.streamOps||w.streamOps.length===0)&&push(`${at}/streamOps`,`Surface "${s}" write target "${w.name}" is a stream target with no streamOps.`,"List the ops it services."),w.updatesValue||push(`${at}/updatesValue`,`Surface "${s}" write target "${w.name}" is a stream target with no read twin.`,"Declare updatesValue.")):w.streamOps!==void 0&&push(`${at}/streamOps`,`Surface "${s}" write target "${w.name}" lists streamOps but its mode is "${w.mode}".`,'streamOps belong only to mode "stream".');for(let op of w.streamOps??[])has(STREAM_OPS,op)||push(`${at}/streamOps`,`Surface "${s}" write target "${w.name}" lists unknown stream op "${String(op)}".`,`Use ${STREAM_OPS.join(" | ")}.`);w.group&&!groupKeys.has(w.group)&&push(`${at}/group`,`Surface "${s}" write target "${w.name}" references undeclared group "${w.group}".`,"Declare the group or drop it."),w.valueKind!==void 0?typeof w.valueKind!="string"||!w.valueKind.trim()?push(`${at}/valueKind`,`Surface "${s}" write target "${w.name}" has an empty valueKind.`,"Name a registered kind slug or omit the field."):options.isKnownKind&&!options.isKnownKind(w.valueKind)&&push(`${at}/valueKind`,`Surface "${s}" write target "${w.name}" declares valueKind "${w.valueKind}", which is not a registered active kind.`,"Name a registered kind slug, or register the kind first; never inline a JSON schema."):STRUCTURED.has(w.valueType)&&structuredWithoutKind.push(w.name)}for(let name of structuredWithoutKind)push(`writeTargets/${name}/valueKind`,`Surface "${s}" structured write target "${name}" declares no valueKind.`,"Name a registered kind slug (the value contract ratchet).","advisory");if(!d.skipBaselineValues&&options.baselineNames){let missing=options.baselineNames.filter(name=>!seenValues.has(name));missing.length>0&&push("values",`Surface "${s}" is missing baseline value(s): ${missing.join(", ")}.`,"The registry injects baselines automatically; opt out only with skipBaselineValues.")}}for(let extension of options.extensions??[])if(extension.validate)for(let d of declarations)issues.push(...extension.validate(d,{all:declarations}));return issues}function validateLoadedValues(declaration,loaded,options={}){let declared=new Set(declaration.values.map(v=>v.name)),ignore=new Set(options.ignore??[]),issues=[];for(let key of Object.keys(loaded))key==="__item"||declared.has(key)||ignore.has(key)||issues.push({surfaceName:declaration.surfaceName,path:`values/${key}`,sentence:`Surface "${declaration.surfaceName}" loaded a value "${key}" it never declared.`,remedy:`Declare "${key}" in the surface's values, or stop emitting it.`});let item=loaded.__item;if(item&&typeof item=="object"){let type=declaration.itemTypes?.find(t=>t.name===item.itemType);if(!type)issues.push({surfaceName:declaration.surfaceName,path:"__item/itemType",sentence:`Surface "${declaration.surfaceName}" loaded an item of type "${String(item.itemType)}" it never declared.`,remedy:"Declare the item type, or stop emitting the item."});else if(item.values&&typeof item.values=="object"){let itemDeclared=new Set(type.values.map(v=>v.name));for(let key of Object.keys(item.values))itemDeclared.has(key)||issues.push({surfaceName:declaration.surfaceName,path:`__item/${type.name}.${key}`,sentence:`Surface "${declaration.surfaceName}" loaded item value "${type.name}.${key}" it never declared.`,remedy:`Declare "${key}" on item type "${type.name}".`})}}return issues}function findOrphanRows(rowNames,declaredNames,retired=[]){let owned=new Set(declaredNames),archived=new Set(retired);return rowNames.filter(name=>!owned.has(name)&&!archived.has(name)).sort()}var DEFAULT_SENSITIVITY=Object.freeze({exportable:!0,classification:"ordinary",includedByDefault:!0});function resolveSensitivity(value){return{exportable:value.sensitivity?.exportable??DEFAULT_SENSITIVITY.exportable,classification:value.sensitivity?.classification??DEFAULT_SENSITIVITY.classification,includedByDefault:value.sensitivity?.includedByDefault??DEFAULT_SENSITIVITY.includedByDefault}}var RESERVED_GROUP_KEYS={general:"general",baseline:"baseline",inheritedPrefix:"inherited:"},GENERAL_GROUP_ORDER=850,INHERITED_GROUP_ORDER_BASE=9e3,BASELINE_GROUP_ORDER=9900,DEFAULT_MAX_INHERITANCE_DEPTH=3;function createDeclarationRegistry(options={}){let baselineValues=options.baselineValues??[],baselineNames=new Set(baselineValues.map(v=>v.name)),reservedValues=new Set(options.reservedValueNames??[]),reservedTargets=new Set(options.reservedWriteTargetNames??[]),maxDepth=options.maxInheritanceDepth??DEFAULT_MAX_INHERITANCE_DEPTH,declarations=[],index=new Map,extensionList=[],resolvedCache=null,resolvedIndex=new Map;function ancestry(surfaceName){let chain=[],seen=new Set([surfaceName]),current=index.get(surfaceName)?.inheritsFrom;for(;current;){if(seen.has(current))throw new Error(`[surfaces] inheritsFrom CYCLE detected at "${current}" (from "${surfaceName}"). Fix the manifest chain: ${[...seen].join(" \u2192 ")} \u2192 ${current}`);let parent=index.get(current);if(!parent)throw new Error(`[surfaces] "${surfaceName}" inheritsFrom unknown surface "${current}" \u2014 the parent must be a registered declaration`);if(seen.add(current),chain.unshift(current),chain.length>maxDepth)throw new Error(`[surfaces] inheritance chain for "${surfaceName}" exceeds depth ${maxDepth}: `+chain.join(" \u2192 "));current=parent.inheritsFrom}return chain}function groupKeyFor(value,provenance){return provenance.kind==="own"&&value.group?value.group:baselineNames.has(value.name)?RESERVED_GROUP_KEYS.baseline:provenance.kind==="inherited"?`${RESERVED_GROUP_KEYS.inheritedPrefix}${provenance.from}`:provenance.kind==="baseline"?RESERVED_GROUP_KEYS.baseline:RESERVED_GROUP_KEYS.general}function resolve(declaration){let chain=ancestry(declaration.surfaceName),lineage=[...chain.map(name=>{let layer=index.get(name);if(!layer)throw new Error(`[surfaces] missing inherited declaration "${name}"`);return{layer,from:name}}),{layer:declaration,from:null}],curatedKeys=new Set;for(let group of declaration.groups??[]){if(group.key===RESERVED_GROUP_KEYS.general||group.key===RESERVED_GROUP_KEYS.baseline||group.key.startsWith(RESERVED_GROUP_KEYS.inheritedPrefix))throw new Error(`[surfaces] "${declaration.surfaceName}" declares reserved group key "${group.key}" \u2014 general/baseline/inherited:* are synthesized by the registry`);if(curatedKeys.has(group.key))throw new Error(`[surfaces] "${declaration.surfaceName}" declares duplicate group key "${group.key}"`);curatedKeys.add(group.key)}for(let value of declaration.values){if(reservedValues.has(value.name))throw new Error(`[surfaces] "${declaration.surfaceName}" declares value "${value.name}" \u2014 that name is written by the platform; choose another name`);if(value.group&&!curatedKeys.has(value.group))throw new Error(`[surfaces] "${declaration.surfaceName}" value "${value.name}" references undeclared group "${value.group}" \u2014 declare it in the manifest's \`groups\``)}for(let target of declaration.writeTargets??[])if(reservedTargets.has(target.name))throw new Error(`[surfaces] "${declaration.surfaceName}" declares write target "${target.name}" \u2014 that name is written by the platform; choose another name`);let valuesByName=new Map,inheritedLists=new Map,lists=[...[{field:"configNamespaces",identity:entry=>entry.namespace},{field:"evidenceSources",identity:entry=>`${entry.kind}:${entry.idValue}`}],...extensionList.flatMap(extension=>extension.inheritedLists??[])];for(let{layer,from}of lineage){for(let value of layer.values){let provenance=from?{kind:"inherited",from}:{kind:"own"};valuesByName.set(value.name,{...value,provenance,groupKey:groupKeyFor(value,provenance),resolvedSensitivity:resolveSensitivity(value)})}for(let list of lists){let entries=layer[list.field];if(!Array.isArray(entries))continue;let byIdentity=inheritedLists.get(list.field)??new Map;for(let entry of entries)byIdentity.set(list.identity(entry),entry);inheritedLists.set(list.field,byIdentity)}}if(!declaration.skipBaselineValues)for(let baseline of baselineValues)valuesByName.has(baseline.name)||valuesByName.set(baseline.name,{...baseline,provenance:{kind:"baseline"},groupKey:RESERVED_GROUP_KEYS.baseline,resolvedSensitivity:resolveSensitivity(baseline)});let usedGroupKeys=new Set(Array.from(valuesByName.values(),value=>value.groupKey)),groups=[...declaration.groups??[]];usedGroupKeys.has(RESERVED_GROUP_KEYS.general)&&groups.push({key:RESERVED_GROUP_KEYS.general,label:"General",sortOrder:GENERAL_GROUP_ORDER});for(let i=chain.length-1,distance=0;i>=0;i-=1,distance+=1){let parentName=chain[i],key=`${RESERVED_GROUP_KEYS.inheritedPrefix}${parentName}`;if(!usedGroupKeys.has(key))continue;let parentLabel=index.get(parentName)?.label??parentName;groups.push({key,label:`Inherited from ${parentLabel}`,sortOrder:INHERITED_GROUP_ORDER_BASE+distance*10})}usedGroupKeys.has(RESERVED_GROUP_KEYS.baseline)&&groups.push({key:RESERVED_GROUP_KEYS.baseline,label:"Generic baselines",sortOrder:BASELINE_GROUP_ORDER}),groups.sort((a,b)=>a.sortOrder-b.sortOrder);let groupOrder=new Map(groups.map(group=>[group.key,group.sortOrder])),values=Array.from(valuesByName.values()).sort((a,b)=>{let ga=groupOrder.get(a.groupKey)??GENERAL_GROUP_ORDER,gb=groupOrder.get(b.groupKey)??GENERAL_GROUP_ORDER;return ga!==gb?ga-gb:(a.sortOrder??1e3)-(b.sortOrder??1e3)}),merged={};for(let[field,byIdentity]of inheritedLists)byIdentity.size>0&&(merged[field]=Array.from(byIdentity.values()));return{...declaration,values,groups,...merged,contentHash:declarationHash(declaration)}}function resolvedAll(){return resolvedCache||(resolvedCache=declarations.map(resolve),resolvedIndex=new Map(resolvedCache.map(entry=>[entry.surfaceName,entry]))),resolvedCache}return{register(declaration){if(index.has(declaration.surfaceName))throw new Error(`[surfaces] "${declaration.surfaceName}" is declared twice \u2014 one surface, one declaration`);declarations.push(declaration),index.set(declaration.surfaceName,declaration),resolvedCache=null},registerExtension(extension){if(extensionList.some(existing=>existing.key===extension.key))throw new Error(`[surfaces] declaration extension "${extension.key}" is registered twice`);extensionList.push(extension),resolvedCache=null},extensions:()=>extensionList,raw:()=>declarations,getRaw:surfaceName=>index.get(surfaceName),ancestry,children:surfaceName=>declarations.filter(d=>d.inheritsFrom===surfaceName).map(d=>d.surfaceName),all:()=>resolvedAll(),get(surfaceName){return resolvedAll(),resolvedIndex.get(surfaceName)},validate:validateOptions=>validateDeclarations(resolvedAll(),{...validateOptions,extensions:[...validateOptions?.extensions??[],...extensionList],baselineNames:validateOptions?.baselineNames??[...baselineNames]})}}
|
|
1
|
+
"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var declare_exports={};__export(declare_exports,{APPLY_POLICIES:()=>APPLY_POLICIES,BASELINE_GROUP_ORDER:()=>BASELINE_GROUP_ORDER,CLASSIFICATIONS:()=>CLASSIFICATIONS,DECLARATION_NAME_RE:()=>DECLARATION_NAME_RE,DEFAULT_MAX_INHERITANCE_DEPTH:()=>DEFAULT_MAX_INHERITANCE_DEPTH,DEFAULT_SENSITIVITY:()=>DEFAULT_SENSITIVITY,EXECUTION_MODES:()=>EXECUTION_MODES,GENERAL_GROUP_ORDER:()=>GENERAL_GROUP_ORDER,INHERITED_GROUP_ORDER_BASE:()=>INHERITED_GROUP_ORDER_BASE,LIVE_SLOTS:()=>LIVE_SLOTS,QUALIFIED_VALUE_KEY_RE:()=>QUALIFIED_VALUE_KEY_RE,READINESS:()=>READINESS,RESERVED_GROUP_KEYS:()=>RESERVED_GROUP_KEYS,STREAM_OPS:()=>STREAM_OPS,SURFACE_NAME_RE:()=>SURFACE_NAME_RE,VALUE_TYPES:()=>VALUE_TYPES,WRITE_MODES:()=>WRITE_MODES,canonicalJson:()=>canonicalJson,createDeclarationRegistry:()=>createDeclarationRegistry,declarationHash:()=>declarationHash,findOrphanRows:()=>findOrphanRows,parseQualifiedValueKey:()=>parseQualifiedValueKey,qualifyValueKey:()=>qualifyValueKey,resolveSensitivity:()=>resolveSensitivity,sha256Hex:()=>sha256Hex,surfaceClientOf:()=>surfaceClientOf,validateDeclarations:()=>validateDeclarations,validateLoadedValues:()=>validateLoadedValues});module.exports=__toCommonJS(declare_exports);var DECLARATION_NAME_RE=/^[a-z][a-z0-9_]*$/,SURFACE_NAME_RE=/^[a-z][a-z0-9-]*\/[a-z0-9-/]+$/,QUALIFIED_VALUE_KEY_RE=/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)?$/;function parseQualifiedValueKey(key){if(!QUALIFIED_VALUE_KEY_RE.test(key))return null;let dot=key.indexOf(".");return dot===-1?{itemType:"",name:key}:{itemType:key.slice(0,dot),name:key.slice(dot+1)}}function qualifyValueKey(itemType,name){return itemType?`${itemType}.${name}`:name}function surfaceClientOf(surfaceName){return surfaceName.split("/")[0]??""}function canonicalJson(value){if(value===void 0)return"null";if(value===null||typeof value!="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(entry=>canonicalJson(entry)).join(",")}]`;let record=value;return`{${Object.keys(record).filter(key=>record[key]!==void 0).sort().map(key=>`${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`}var K=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function sha256Hex(input){let bytes=new TextEncoder().encode(input),bitLength=bytes.length*8,padded=new Uint8Array(bytes.length+9+63>>6<<6);padded.set(bytes),padded[bytes.length]=128;let view=new DataView(padded.buffer);view.setUint32(padded.length-8,Math.floor(bitLength/4294967296)),view.setUint32(padded.length-4,bitLength>>>0);let h=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),w=new Uint32Array(64);for(let offset=0;offset<padded.length;offset+=64){for(let i=0;i<16;i+=1)w[i]=view.getUint32(offset+i*4);for(let i=16;i<64;i+=1){let a2=w[i-15],b2=w[i-2],s0=(a2>>>7|a2<<25)^(a2>>>18|a2<<14)^a2>>>3,s1=(b2>>>17|b2<<15)^(b2>>>19|b2<<13)^b2>>>10;w[i]=w[i-16]+s0+w[i-7]+s1>>>0}let a=h[0],b=h[1],c=h[2],d=h[3],e=h[4],f=h[5],g=h[6],hh=h[7];for(let i=0;i<64;i+=1){let S1=(e>>>6|e<<26)^(e>>>11|e<<21)^(e>>>25|e<<7),ch=e&f^~e&g,t1=hh+S1+ch+K[i]+w[i]>>>0,S0=(a>>>2|a<<30)^(a>>>13|a<<19)^(a>>>22|a<<10),maj=a&b^a&c^b&c,t2=S0+maj>>>0;hh=g,g=f,f=e,e=d+t1>>>0,d=c,c=b,b=a,a=t1+t2>>>0}h[0]=h[0]+a>>>0,h[1]=h[1]+b>>>0,h[2]=h[2]+c>>>0,h[3]=h[3]+d>>>0,h[4]=h[4]+e>>>0,h[5]=h[5]+f>>>0,h[6]=h[6]+g>>>0,h[7]=h[7]+hh>>>0}return Array.from(h,word=>word.toString(16).padStart(8,"0")).join("")}function declarationHash(declaration){return sha256Hex(canonicalJson(declaration))}var VALUE_TYPES=["string","number","boolean","object","array","document"],WRITE_MODES=["draft","entity","ui","stream"],APPLY_POLICIES=["manual","ask","auto","queued"],STREAM_OPS=["replace","insert_before","insert_after","prepend","append","patch"],EXECUTION_MODES=["python-stream","nextjs-stream","browser-realtime","local-runtime"],READINESS=["verified","partial","stub"],LIVE_SLOTS=["selection","on-demand","errors","requests"],CLASSIFICATIONS=["ordinary","secret","credential"],STRUCTURED=new Set(["object","array"]);function has(list,value){return typeof value=="string"&&list.includes(value)}function validateDeclarations(declarations,options={}){let issues=[],seenSurfaces=new Set,labelsByClient=new Map;for(let d of declarations){let s=d.surfaceName,push=(path,sentence,remedy,severity)=>issues.push({surfaceName:s,path,sentence,remedy,...severity?{severity}:{}});seenSurfaces.has(s)&&push("surfaceName",`Duplicate manifest surfaceName: "${s}" appears more than once.`,"Keep one declaration per surface."),seenSurfaces.add(s),SURFACE_NAME_RE.test(s)||push("surfaceName",`Surface "${s}" doesn't match the "<client>/<local>" convention.`,"Rename it to <client>/<local>.");let prefix=surfaceClientOf(s);d.client!==prefix&&push("client",`Surface "${s}" declares client "${String(d.client)}" but its name prefix is "${prefix}" \u2014 they must match.`,`Set client: "${prefix}".`),has(EXECUTION_MODES,d.executionMode)||push("executionMode",`Surface "${s}" has invalid executionMode "${String(d.executionMode)}".`,`Use one of ${EXECUTION_MODES.join(" | ")}.`),typeof d.description!="string"&&push("description",`Surface "${s}" has no description.`,'Add one sentence on what the surface is ("" only where the live row is empty).');let label=d.label?.trim();if(!label)push("label",`Surface "${s}" has no canonical label \u2014 label is required.`,"Add the ONE canonical human display name.");else{let clientLabels=labelsByClient.get(prefix)??new Map,clash=clientLabels.get(label.toLowerCase());clash&&clash!==s&&push("label",`Canonical label "${label}" is used by both "${clash}" and "${s}" \u2014 labels must be unique per client.`,"Give one of them a distinct label."),clientLabels.set(label.toLowerCase(),s),labelsByClient.set(prefix,clientLabels)}has(READINESS,d.readiness)?d.readiness!=="verified"&&!d.readinessNote?.trim()&&push("readinessNote",`Surface "${s}" is readiness "${d.readiness}" but has no readinessNote \u2014 say what's missing.`,"Add a one-line readinessNote."):push("readiness",`Surface "${s}" has invalid readiness "${String(d.readiness)}" (expected verified | partial | stub).`,"Set a valid readiness.");let groupKeys=new Set;for(let g of d.groups??[])groupKeys.add(g.key),!(g.key==="general"||g.key==="baseline"||g.key.startsWith("inherited:"))&&(DECLARATION_NAME_RE.test(g.key)||push(`groups/${g.key}`,`Surface "${s}" group "${g.key}" doesn't match /^[a-z][a-z0-9_]*$/.`,"Rename the group key to lower_snake_case."),(g.sortOrder<0||g.sortOrder>899)&&push(`groups/${g.key}/sortOrder`,`Surface "${s}" group "${g.key}" sortOrder ${g.sortOrder} is outside the curated band 0\u2013899.`,"Use a sortOrder between 0 and 899."),g.label?.trim()||push(`groups/${g.key}/label`,`Surface "${s}" group "${g.key}" has no canonical label.`,"Add a label."));let seenNamespaces=new Set;for(let ns of d.configNamespaces??[])seenNamespaces.has(ns.namespace)&&push(`configNamespaces/${ns.namespace}`,`Surface "${s}" declares duplicate config namespace "${ns.namespace}".`,"Remove the duplicate."),seenNamespaces.add(ns.namespace),options.knownNamespaces&&!options.knownNamespaces.has(ns.namespace)&&push(`configNamespaces/${ns.namespace}`,`Surface "${s}" references config namespace "${ns.namespace}" which is not registered.`,"Register the namespace first, or remove the reference.");if(d.values.length===0){push("values",`Surface "${s}" declares no values.`,"Declare at least one value.");continue}let seenValues=new Set;for(let v of d.values){let at=`values/${v.name}`;seenValues.has(v.name)&&push(at,`Surface "${s}" declares duplicate value "${v.name}".`,"Remove the duplicate."),seenValues.add(v.name),DECLARATION_NAME_RE.test(v.name)||push(at,`Surface "${s}" value "${v.name}" doesn't match /^[a-z][a-z0-9_]*$/ \u2014 the DB CHECK constraint will reject this.`,"Rename it to lower_snake_case."),has(VALUE_TYPES,v.valueType)||push(`${at}/valueType`,`Surface "${s}" value "${v.name}" has invalid valueType "${String(v.valueType)}".`,`Use one of ${VALUE_TYPES.join(" | ")}.`),(typeof v.typicalCharCount!="number"||v.typicalCharCount<0)&&push(`${at}/typicalCharCount`,`Surface "${s}" value "${v.name}" has invalid typicalCharCount.`,"Use a non-negative number."),v.sortOrder!==void 0&&(typeof v.sortOrder!="number"||v.sortOrder<0)&&push(`${at}/sortOrder`,`Surface "${s}" value "${v.name}" has invalid sortOrder.`,"Use a non-negative number."),v.groupKey&&!groupKeys.has(v.groupKey)&&push(`${at}/group`,`Surface "${s}" value "${v.name}" resolved to groupKey "${v.groupKey}" which is missing from the resolved groups list \u2014 registry group synthesis is broken.`,"Fix the registry resolution."),v.liveSlot!==void 0&&!has(LIVE_SLOTS,v.liveSlot)&&push(`${at}/liveSlot`,`Surface "${s}" value "${v.name}" has invalid liveSlot "${String(v.liveSlot)}".`,`Use one of ${LIVE_SLOTS.join(" | ")}.`),v.role!==void 0&&v.role!=="data"&&v.role!=="request"&&push(`${at}/role`,`Surface "${s}" value "${v.name}" has invalid role "${String(v.role)}".`,"Use data | request."),v.sensitivity?.classification!==void 0&&!has(CLASSIFICATIONS,v.sensitivity.classification)&&push(`${at}/sensitivity/classification`,`Surface "${s}" value "${v.name}" has invalid classification "${String(v.sensitivity.classification)}".`,`Use one of ${CLASSIFICATIONS.join(" | ")}.`)}for(let slot of d.liveSlots??[])has(LIVE_SLOTS,slot)||push("liveSlots",`Surface "${s}" declares unknown live slot "${String(slot)}".`,`Use one of ${LIVE_SLOTS.join(" | ")}.`);let itemTypeNames=new Set;for(let item of d.itemTypes??[]){let at=`itemTypes/${item.name}`;itemTypeNames.has(item.name)&&push(at,`Surface "${s}" declares duplicate item type "${item.name}".`,"Remove the duplicate."),itemTypeNames.add(item.name),DECLARATION_NAME_RE.test(item.name)||push(at,`Surface "${s}" item type "${item.name}" doesn't match /^[a-z][a-z0-9_]*$/.`,"Rename it to lower_snake_case."),(!item.label?.trim()||!item.description?.trim())&&push(at,`Surface "${s}" item type "${item.name}" needs a label and a description.`,"Add both.");let itemValues=new Set(item.values.map(v=>v.name));item.identity.length===0&&push(`${at}/identity`,`Surface "${s}" item type "${item.name}" has an empty identity.`,"Name the value(s) that identify one item.");for(let key of item.identity)itemValues.has(key)||push(`${at}/identity`,`Surface "${s}" item type "${item.name}" identity names "${key}", which is not one of its values.`,"Declare it as an item value.");for(let t of item.writeTargets??[])t.updatesValue&&!itemValues.has(t.updatesValue)&&push(`${at}/writeTargets/${t.name}`,`Surface "${s}" item type "${item.name}" write target "${t.name}" updatesValue "${t.updatesValue}" which is not an item value.`,"Point it at a declared item value.")}let seenTargets=new Set,structuredWithoutKind=[];for(let w of d.writeTargets??[]){let at=`writeTargets/${w.name}`;seenTargets.has(w.name)&&push(at,`Surface "${s}" declares duplicate write target "${w.name}".`,"Remove the duplicate."),seenTargets.add(w.name),DECLARATION_NAME_RE.test(w.name)||push(at,`Surface "${s}" write target "${w.name}" doesn't match /^[a-z][a-z0-9_]*$/.`,"Rename it to lower_snake_case."),(!w.label?.trim()||!w.description?.trim())&&push(at,`Surface "${s}" write target "${w.name}" needs a label and a description.`,"Add both."),has(VALUE_TYPES,w.valueType)||push(`${at}/valueType`,`Surface "${s}" write target "${w.name}" has invalid valueType "${String(w.valueType)}".`,`Use one of ${VALUE_TYPES.join(" | ")}.`),has(WRITE_MODES,w.mode)||push(`${at}/mode`,`Surface "${s}" write target "${w.name}" has invalid mode "${String(w.mode)}".`,`Use one of ${WRITE_MODES.join(" | ")}.`),w.applyPolicy!==void 0&&!has(APPLY_POLICIES,w.applyPolicy)&&push(`${at}/applyPolicy`,`Surface "${s}" write target "${w.name}" has invalid applyPolicy "${String(w.applyPolicy)}".`,`Use one of ${APPLY_POLICIES.join(" | ")}.`),w.itemType!==void 0&&!itemTypeNames.has(w.itemType)&&push(`${at}/itemType`,`Surface "${s}" write target "${w.name}" names item type "${w.itemType}", which the surface does not declare.`,"Declare the item type or drop itemType.");let readTwinDeclared=w.updatesValue?seenValues.has(w.updatesValue):!1;w.updatesValue&&!w.itemType&&!readTwinDeclared&&push(`${at}/updatesValue`,`Surface "${s}" write target "${w.name}" updatesValue "${w.updatesValue}" which is not a declared value.`,"Point updatesValue at a declared value."),w.patchable&&!w.updatesValue&&push(`${at}/patchable`,`Surface "${s}" write target "${w.name}" is patchable but declares no updatesValue \u2014 an anchored edit has nothing to read.`,"Declare the read twin in updatesValue."),w.patchable&&w.valueType!=="string"&&w.valueType!=="document"&&push(`${at}/patchable`,`Surface "${s}" write target "${w.name}" is patchable but valueType is "${w.valueType}" (patching is for "string" | "document").`,"Drop patchable or change the value type."),w.mode==="stream"?((!w.streamOps||w.streamOps.length===0)&&push(`${at}/streamOps`,`Surface "${s}" write target "${w.name}" is a stream target with no streamOps.`,"List the ops it services."),w.updatesValue||push(`${at}/updatesValue`,`Surface "${s}" write target "${w.name}" is a stream target with no read twin.`,"Declare updatesValue.")):w.streamOps!==void 0&&push(`${at}/streamOps`,`Surface "${s}" write target "${w.name}" lists streamOps but its mode is "${w.mode}".`,'streamOps belong only to mode "stream".');for(let op of w.streamOps??[])has(STREAM_OPS,op)||push(`${at}/streamOps`,`Surface "${s}" write target "${w.name}" lists unknown stream op "${String(op)}".`,`Use ${STREAM_OPS.join(" | ")}.`);w.group&&!groupKeys.has(w.group)&&push(`${at}/group`,`Surface "${s}" write target "${w.name}" references undeclared group "${w.group}".`,"Declare the group or drop it."),w.valueKind!==void 0?typeof w.valueKind!="string"||!w.valueKind.trim()?push(`${at}/valueKind`,`Surface "${s}" write target "${w.name}" has an empty valueKind.`,"Name a registered kind slug or omit the field."):options.isKnownKind&&!options.isKnownKind(w.valueKind)&&push(`${at}/valueKind`,`Surface "${s}" write target "${w.name}" declares valueKind "${w.valueKind}", which is not a registered active kind.`,"Name a registered kind slug, or register the kind first; never inline a JSON schema."):STRUCTURED.has(w.valueType)&&structuredWithoutKind.push(w.name)}for(let name of structuredWithoutKind)push(`writeTargets/${name}/valueKind`,`Surface "${s}" structured write target "${name}" declares no valueKind.`,"Name a registered kind slug (the value contract ratchet).","advisory");if(!d.skipBaselineValues&&options.baselineNames){let missing=options.baselineNames.filter(name=>!seenValues.has(name));missing.length>0&&push("values",`Surface "${s}" is missing baseline value(s): ${missing.join(", ")}.`,"The registry injects baselines automatically; opt out only with skipBaselineValues.")}}for(let extension of options.extensions??[])if(extension.validate)for(let d of declarations)issues.push(...extension.validate(d,{all:declarations}));return issues}function validateLoadedValues(declaration,loaded,options={}){let declared=new Set(declaration.values.map(v=>v.name)),ignore=new Set(options.ignore??[]),issues=[];for(let key of Object.keys(loaded))key==="__item"||declared.has(key)||ignore.has(key)||issues.push({surfaceName:declaration.surfaceName,path:`values/${key}`,sentence:`Surface "${declaration.surfaceName}" loaded a value "${key}" it never declared.`,remedy:`Declare "${key}" in the surface's values, or stop emitting it.`});let item=loaded.__item;if(item&&typeof item=="object"){let type=declaration.itemTypes?.find(t=>t.name===item.itemType);if(!type)issues.push({surfaceName:declaration.surfaceName,path:"__item/itemType",sentence:`Surface "${declaration.surfaceName}" loaded an item of type "${String(item.itemType)}" it never declared.`,remedy:"Declare the item type, or stop emitting the item."});else if(item.values&&typeof item.values=="object"){let itemDeclared=new Set(type.values.map(v=>v.name));for(let key of Object.keys(item.values))itemDeclared.has(key)||issues.push({surfaceName:declaration.surfaceName,path:`__item/${type.name}.${key}`,sentence:`Surface "${declaration.surfaceName}" loaded item value "${type.name}.${key}" it never declared.`,remedy:`Declare "${key}" on item type "${type.name}".`})}}return issues}function findOrphanRows(rows,declaredNames,retired=[]){let owned=new Set(declaredNames),archived=new Set(retired);return rows.filter(row=>typeof row=="string"||row.declared_by!=="database").map(row=>typeof row=="string"?row:row.name).filter(name=>!owned.has(name)&&!archived.has(name)).sort()}var DEFAULT_SENSITIVITY=Object.freeze({exportable:!0,classification:"ordinary",includedByDefault:!0});function resolveSensitivity(value){return{exportable:value.sensitivity?.exportable??DEFAULT_SENSITIVITY.exportable,classification:value.sensitivity?.classification??DEFAULT_SENSITIVITY.classification,includedByDefault:value.sensitivity?.includedByDefault??DEFAULT_SENSITIVITY.includedByDefault}}var RESERVED_GROUP_KEYS={general:"general",baseline:"baseline",inheritedPrefix:"inherited:"},GENERAL_GROUP_ORDER=850,INHERITED_GROUP_ORDER_BASE=9e3,BASELINE_GROUP_ORDER=9900,DEFAULT_MAX_INHERITANCE_DEPTH=3;function createDeclarationRegistry(options={}){let baselineValues=options.baselineValues??[],baselineNames=new Set(baselineValues.map(v=>v.name)),reservedValues=new Set(options.reservedValueNames??[]),reservedTargets=new Set(options.reservedWriteTargetNames??[]),maxDepth=options.maxInheritanceDepth??DEFAULT_MAX_INHERITANCE_DEPTH,declarations=[],index=new Map,extensionList=[],resolvedCache=null,resolvedIndex=new Map;function ancestry(surfaceName){let chain=[],seen=new Set([surfaceName]),current=index.get(surfaceName)?.inheritsFrom;for(;current;){if(seen.has(current))throw new Error(`[surfaces] inheritsFrom CYCLE detected at "${current}" (from "${surfaceName}"). Fix the manifest chain: ${[...seen].join(" \u2192 ")} \u2192 ${current}`);let parent=index.get(current);if(!parent)throw new Error(`[surfaces] "${surfaceName}" inheritsFrom unknown surface "${current}" \u2014 the parent must be a registered declaration`);if(seen.add(current),chain.unshift(current),chain.length>maxDepth)throw new Error(`[surfaces] inheritance chain for "${surfaceName}" exceeds depth ${maxDepth}: `+chain.join(" \u2192 "));current=parent.inheritsFrom}return chain}function groupKeyFor(value,provenance){return provenance.kind==="own"&&value.group?value.group:baselineNames.has(value.name)?RESERVED_GROUP_KEYS.baseline:provenance.kind==="inherited"?`${RESERVED_GROUP_KEYS.inheritedPrefix}${provenance.from}`:provenance.kind==="baseline"?RESERVED_GROUP_KEYS.baseline:RESERVED_GROUP_KEYS.general}function resolve(declaration){let chain=ancestry(declaration.surfaceName),lineage=[...chain.map(name=>{let layer=index.get(name);if(!layer)throw new Error(`[surfaces] missing inherited declaration "${name}"`);return{layer,from:name}}),{layer:declaration,from:null}],curatedKeys=new Set;for(let group of declaration.groups??[]){if(group.key===RESERVED_GROUP_KEYS.general||group.key===RESERVED_GROUP_KEYS.baseline||group.key.startsWith(RESERVED_GROUP_KEYS.inheritedPrefix))throw new Error(`[surfaces] "${declaration.surfaceName}" declares reserved group key "${group.key}" \u2014 general/baseline/inherited:* are synthesized by the registry`);if(curatedKeys.has(group.key))throw new Error(`[surfaces] "${declaration.surfaceName}" declares duplicate group key "${group.key}"`);curatedKeys.add(group.key)}for(let value of declaration.values){if(reservedValues.has(value.name))throw new Error(`[surfaces] "${declaration.surfaceName}" declares value "${value.name}" \u2014 that name is written by the platform; choose another name`);if(value.group&&!curatedKeys.has(value.group))throw new Error(`[surfaces] "${declaration.surfaceName}" value "${value.name}" references undeclared group "${value.group}" \u2014 declare it in the manifest's \`groups\``)}for(let target of declaration.writeTargets??[])if(reservedTargets.has(target.name))throw new Error(`[surfaces] "${declaration.surfaceName}" declares write target "${target.name}" \u2014 that name is written by the platform; choose another name`);let valuesByName=new Map,inheritedLists=new Map,lists=[...[{field:"configNamespaces",identity:entry=>entry.namespace},{field:"evidenceSources",identity:entry=>`${entry.kind}:${entry.idValue}`}],...extensionList.flatMap(extension=>extension.inheritedLists??[])];for(let{layer,from}of lineage){for(let value of layer.values){let provenance=from?{kind:"inherited",from}:{kind:"own"};valuesByName.set(value.name,{...value,provenance,groupKey:groupKeyFor(value,provenance),resolvedSensitivity:resolveSensitivity(value)})}for(let list of lists){let entries=layer[list.field];if(!Array.isArray(entries))continue;let byIdentity=inheritedLists.get(list.field)??new Map;for(let entry of entries)byIdentity.set(list.identity(entry),entry);inheritedLists.set(list.field,byIdentity)}}if(!declaration.skipBaselineValues)for(let baseline of baselineValues)valuesByName.has(baseline.name)||valuesByName.set(baseline.name,{...baseline,provenance:{kind:"baseline"},groupKey:RESERVED_GROUP_KEYS.baseline,resolvedSensitivity:resolveSensitivity(baseline)});let usedGroupKeys=new Set(Array.from(valuesByName.values(),value=>value.groupKey)),groups=[...declaration.groups??[]];usedGroupKeys.has(RESERVED_GROUP_KEYS.general)&&groups.push({key:RESERVED_GROUP_KEYS.general,label:"General",sortOrder:GENERAL_GROUP_ORDER});for(let i=chain.length-1,distance=0;i>=0;i-=1,distance+=1){let parentName=chain[i],key=`${RESERVED_GROUP_KEYS.inheritedPrefix}${parentName}`;if(!usedGroupKeys.has(key))continue;let parentLabel=index.get(parentName)?.label??parentName;groups.push({key,label:`Inherited from ${parentLabel}`,sortOrder:INHERITED_GROUP_ORDER_BASE+distance*10})}usedGroupKeys.has(RESERVED_GROUP_KEYS.baseline)&&groups.push({key:RESERVED_GROUP_KEYS.baseline,label:"Generic baselines",sortOrder:BASELINE_GROUP_ORDER}),groups.sort((a,b)=>a.sortOrder-b.sortOrder);let groupOrder=new Map(groups.map(group=>[group.key,group.sortOrder])),values=Array.from(valuesByName.values()).sort((a,b)=>{let ga=groupOrder.get(a.groupKey)??GENERAL_GROUP_ORDER,gb=groupOrder.get(b.groupKey)??GENERAL_GROUP_ORDER;return ga!==gb?ga-gb:(a.sortOrder??1e3)-(b.sortOrder??1e3)}),merged={};for(let[field,byIdentity]of inheritedLists)byIdentity.size>0&&(merged[field]=Array.from(byIdentity.values()));return{...declaration,values,groups,...merged,contentHash:declarationHash(declaration)}}function resolvedAll(){return resolvedCache||(resolvedCache=declarations.map(resolve),resolvedIndex=new Map(resolvedCache.map(entry=>[entry.surfaceName,entry]))),resolvedCache}return{register(declaration){if(index.has(declaration.surfaceName))throw new Error(`[surfaces] "${declaration.surfaceName}" is declared twice \u2014 one surface, one declaration`);declarations.push(declaration),index.set(declaration.surfaceName,declaration),resolvedCache=null},registerExtension(extension){if(extensionList.some(existing=>existing.key===extension.key))throw new Error(`[surfaces] declaration extension "${extension.key}" is registered twice`);extensionList.push(extension),resolvedCache=null},extensions:()=>extensionList,raw:()=>declarations,getRaw:surfaceName=>index.get(surfaceName),ancestry,children:surfaceName=>declarations.filter(d=>d.inheritsFrom===surfaceName).map(d=>d.surfaceName),all:()=>resolvedAll(),get(surfaceName){return resolvedAll(),resolvedIndex.get(surfaceName)},validate:validateOptions=>validateDeclarations(resolvedAll(),{...validateOptions,extensions:[...validateOptions?.extensions??[],...extensionList],baselineNames:validateOptions?.baselineNames??[...baselineNames]})}}
|
|
2
2
|
//# sourceMappingURL=declare.cjs.map
|