@agimon-ai/po-cloudflare 0.0.2-alpha.0 → 0.0.2-alpha.2
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/apiContracts-CHOiCbS_.js +4451 -0
- package/dist/{approval-CKEOs_1e.js → approval-BMXqnTYd.js} +1 -1
- package/dist/assets/assets/{CodeEditorView-BLRE49Gl.js → CodeEditorView-BnyZHaYM.js} +2 -2
- package/dist/assets/assets/{abnfDiagram-WEYOIA3C-DVusg4ap.js → abnfDiagram-WEYOIA3C-muME0eCj.js} +2 -2
- package/dist/assets/assets/{architecture-WOLXFQ4H-DgNVSvsN.js → architecture-WOLXFQ4H-DMnhK1WH.js} +1 -1
- package/dist/assets/assets/{architectureDiagram-ZHVYKT53-DYOrOupQ.js → architectureDiagram-ZHVYKT53-DKn7XGP7.js} +2 -2
- package/dist/assets/assets/{blockDiagram-RJAE7QA3-CywIicM0.js → blockDiagram-RJAE7QA3-DtDctXZg.js} +2 -2
- package/dist/assets/assets/{c4Diagram-XDPPPE54-BvOcPDic.js → c4Diagram-XDPPPE54-23pGLJeP.js} +2 -2
- package/dist/assets/assets/channel-CMrEzemr.js +2 -0
- package/dist/assets/assets/{chunk-2E7WHVMD-BObj0M5p.js → chunk-2E7WHVMD-BZ2nGNPa.js} +2 -2
- package/dist/assets/assets/{chunk-4EMNKR2T-BSXMAZvk.js → chunk-4EMNKR2T-Dui1SYFi.js} +2 -2
- package/dist/assets/assets/{chunk-55XCU76K-BnUSspOC.js → chunk-55XCU76K-CUB92Evl.js} +2 -2
- package/dist/assets/assets/{chunk-7S6XSTFO-BczbsQRt.js → chunk-7S6XSTFO-CVayPHfE.js} +2 -2
- package/dist/assets/assets/{chunk-AQDTSKZB-BRoqXDh1.js → chunk-AQDTSKZB---wakYqY.js} +2 -2
- package/dist/assets/assets/{chunk-DSNLSHJZ-Cl-E_64g.js → chunk-DSNLSHJZ-DfbdohUR.js} +2 -2
- package/dist/assets/assets/{chunk-HAGFOTED-BIMca0QH.js → chunk-HAGFOTED-Dr4KRh-b.js} +2 -2
- package/dist/assets/assets/{chunk-HNE4Q36P-Crlz_Vcw.js → chunk-HNE4Q36P-D06cR91Z.js} +2 -2
- package/dist/assets/assets/{chunk-NQOKRVIF-oR3B4EZx.js → chunk-NQOKRVIF-Ca4gLeDb.js} +2 -2
- package/dist/assets/assets/{chunk-UHW7PFBP-VGAUlFLK.js → chunk-UHW7PFBP-DmL638jN.js} +2 -2
- package/dist/assets/assets/{chunk-VQ5W62QI-BU1hzhuY.js → chunk-VQ5W62QI-pkxSW5Zj.js} +2 -2
- package/dist/assets/assets/{chunk-WQQL4CDK-CbPL6LVg.js → chunk-WQQL4CDK-Dcc8hV4U.js} +2 -2
- package/dist/assets/assets/chunk-XXDRQBXY-CFf0S6bN.js +2 -0
- package/dist/assets/assets/{chunk-YZO67HFG-C2wleDao.js → chunk-YZO67HFG-B_HKcFrw.js} +2 -2
- package/dist/assets/assets/{chunk-ZAUX2LTX-D8zKoJgU.js → chunk-ZAUX2LTX-DAzZUysS.js} +2 -2
- package/dist/assets/assets/{chunk-ZCHMQSOR-b1DDXv_5.js → chunk-ZCHMQSOR-DAVgjymL.js} +2 -2
- package/dist/assets/assets/{classDiagram-v2-4MYWR3UA-CeMXzbSa.js → classDiagram-v2-4MYWR3UA-Fsw8TGPu.js} +2 -2
- package/dist/assets/assets/{cose-bilkent-JH36ORCC-D9SFRzBp.js → cose-bilkent-JH36ORCC-CgUbISYV.js} +2 -2
- package/dist/assets/assets/{cynefin-EF2NZ3EQ-T1nCPs8y.js → cynefin-EF2NZ3EQ-D1LxAU2x.js} +1 -1
- package/dist/assets/assets/{cynefinDiagram-WF24UDRP-CImukhlk.js → cynefinDiagram-WF24UDRP-D54I1jil.js} +2 -2
- package/dist/assets/assets/{dagre-NK4GIZVX-BBT0FoyY.js → dagre-NK4GIZVX-DC7zL16U.js} +2 -2
- package/dist/assets/assets/{diagram-CBK3MWTC-DrlIN5In.js → diagram-CBK3MWTC-DB0ptUdz.js} +2 -2
- package/dist/assets/assets/{diagram-I5XIIV2D-Bw4FaqMh.js → diagram-I5XIIV2D-CozSftPJ.js} +2 -2
- package/dist/assets/assets/{diagram-ODIL2UCW-Dc2Y7CGh.js → diagram-ODIL2UCW-g3WOEWDS.js} +2 -2
- package/dist/assets/assets/{diagram-PFBEJUXE-Bdrt8ajn.js → diagram-PFBEJUXE-CFxGeOYi.js} +2 -2
- package/dist/assets/assets/{diagram-RJA3I4VV-CVf2D4hV.js → diagram-RJA3I4VV-BQBsLche.js} +2 -2
- package/dist/assets/assets/{diagram-TYUNFSNR-BO8L-ort.js → diagram-TYUNFSNR-DrjpW2yq.js} +2 -2
- package/dist/assets/assets/{dist-C7LLcWzB.js → dist-1-mhYUBH.js} +2 -2
- package/dist/assets/assets/{dist-DHeAKSho.js → dist-B3JXhDWV.js} +2 -2
- package/dist/assets/assets/{dist-CalbZWkv.js → dist-BabjcJ3j.js} +2 -2
- package/dist/assets/assets/{dist-aN2tZ5-H.js → dist-DjL8d1jZ.js} +2 -2
- package/dist/assets/assets/{dist-DfinRaay.js → dist-DvgCCshF.js} +2 -2
- package/dist/assets/assets/{dist-bb9s50Bw.js → dist-Izr2SB3q.js} +2 -2
- package/dist/assets/assets/{dist-CgayRFO6.js → dist-XIZum9n5.js} +2 -2
- package/dist/assets/assets/{dist-DTW-yrAw.js → dist-gfbb4ygy.js} +2 -2
- package/dist/assets/assets/{dist-DZIHAZw8.js → dist-h6SOnP8-.js} +2 -2
- package/dist/assets/assets/{ebnfDiagram-V4P3TTPT-DjYiKg9V.js → ebnfDiagram-V4P3TTPT-BZS_aAve.js} +2 -2
- package/dist/assets/assets/{elk-QONTBCTQ-B6C9wLLs.js → elk-QONTBCTQ-B2ksVmMA.js} +2 -2
- package/dist/assets/assets/{erDiagram-KYQIGQAA-BgF00BPB.js → erDiagram-KYQIGQAA-7P6zF-Z-.js} +2 -2
- package/dist/assets/assets/{eventmodeling-K75KTNOO-xw-KQxvP.js → eventmodeling-K75KTNOO-RoGQoRq-.js} +1 -1
- package/dist/assets/assets/flowDiagram-IUGLLWBU-BhGbWVf0.js +1 -0
- package/dist/assets/assets/{ganttDiagram-R7GPNTJY-DGptLBf1.js → ganttDiagram-R7GPNTJY-CTOlRy7M.js} +2 -2
- package/dist/assets/assets/{gitGraph-VSP46ZUC-B-UqOIPU.js → gitGraph-VSP46ZUC-CPqytIt0.js} +1 -1
- package/dist/assets/assets/{gitGraphDiagram-PDYL7XHY-DyK3tdk3.js → gitGraphDiagram-PDYL7XHY-BffLxuxg.js} +2 -2
- package/dist/assets/assets/index-Bx_K4Joy.js +155 -0
- package/dist/assets/assets/{info-OHQRW6UA-2vuF35jI.js → info-OHQRW6UA-BI8RK0Ow.js} +1 -1
- package/dist/assets/assets/{infoDiagram-MVDRKAX5-_knBCElh.js → infoDiagram-MVDRKAX5-DUIst1FB.js} +2 -2
- package/dist/assets/assets/{ishikawaDiagram-HPEHV2GE-B-tOuUqv.js → ishikawaDiagram-HPEHV2GE-CA17Eho5.js} +2 -2
- package/dist/assets/assets/{journeyDiagram-BOSHW7O7-BcEIdxQq.js → journeyDiagram-BOSHW7O7-CNri5Ap9.js} +2 -2
- package/dist/assets/assets/{kanban-definition-FNSA4HC5-BvDe35Jv.js → kanban-definition-FNSA4HC5-DnXna7jO.js} +2 -2
- package/dist/assets/assets/{line-Cj7V9Vh6.js → line-BsXJZn93.js} +2 -2
- package/dist/assets/assets/{linear-CCVHRql6.js → linear-BHYaD5T0.js} +2 -2
- package/dist/assets/assets/{mermaid-parser.core-CwXtOD2Q.js → mermaid-parser.core-B64Eo-8a.js} +4 -4
- package/dist/assets/assets/{mermaid.core-r3aW1imB.js → mermaid.core-Zw9qmTzg.js} +5 -5
- package/dist/assets/assets/{mindmap-definition-6OY57UG3-D6MOqU6M.js → mindmap-definition-6OY57UG3-E5qz4KNc.js} +2 -2
- package/dist/assets/assets/{packet-JDAUHWVQ-C_Zt4cuU.js → packet-JDAUHWVQ-DgfizTr3.js} +1 -1
- package/dist/assets/assets/{pegDiagram-ECIUJNBX-lqkq3Wrh.js → pegDiagram-ECIUJNBX-D0WK_agM.js} +2 -2
- package/dist/assets/assets/{pie-XZMESJXO-MQONifCF.js → pie-XZMESJXO-PJR1sXD4.js} +1 -1
- package/dist/assets/assets/{pieDiagram-GNMPY74T-Bs-D1SOY.js → pieDiagram-GNMPY74T-CPuU-NTs.js} +2 -2
- package/dist/assets/assets/{quadrantDiagram-D57K4MC3-CrVehnmu.js → quadrantDiagram-D57K4MC3-5C9yjM1b.js} +2 -2
- package/dist/assets/assets/{radar-ABXABTNO-Bxl0Yrt7.js → radar-ABXABTNO-BspdXgl0.js} +1 -1
- package/dist/assets/assets/{railroad-I3PHUGI6-Bb6-OJWs.js → railroad-I3PHUGI6-Ct0a6hLD.js} +1 -1
- package/dist/assets/assets/{railroad-abnf-LNEFI6M7-C-j3F356.js → railroad-abnf-LNEFI6M7-fduYB4SA.js} +1 -1
- package/dist/assets/assets/{railroad-ebnf-DWYD2UWJ-A-wtcRhy.js → railroad-ebnf-DWYD2UWJ-CTQa8Sww.js} +1 -1
- package/dist/assets/assets/{railroad-peg-JR7BVNR7-CYDU3Ysw.js → railroad-peg-JR7BVNR7-DatoH3GJ.js} +1 -1
- package/dist/assets/assets/{railroadDiagram-Y72NRBL7-7J90kJ-u.js → railroadDiagram-Y72NRBL7-C8sWN8l2.js} +2 -2
- package/dist/assets/assets/{requirementDiagram-EQYSW5RA-xSEffjWc.js → requirementDiagram-EQYSW5RA-CqRz4RcT.js} +2 -2
- package/dist/assets/assets/{sankeyDiagram-SY24JHO5-Dtyyfa62.js → sankeyDiagram-SY24JHO5-bdiuKKlX.js} +2 -2
- package/dist/assets/assets/{sequenceDiagram-BLEHNHQU-v0XLnsOG.js → sequenceDiagram-BLEHNHQU-Zy-8I0Hy.js} +2 -2
- package/dist/assets/assets/{src-fM_dkt40.js → src-gihY33R9.js} +2 -2
- package/dist/assets/assets/{stateDiagram-v2-A6IESKWZ-Dtn22VzS.js → stateDiagram-v2-A6IESKWZ-DXQERPvz.js} +2 -2
- package/dist/assets/assets/{swimlanes-B3ENRKFQ-BwL6ufCb.js → swimlanes-B3ENRKFQ-1gjZQElg.js} +2 -2
- package/dist/assets/assets/swimlanesDiagram-AYQRV4AK-q91tR8ri.js +9 -0
- package/dist/assets/assets/{timeline-definition-JXYKGLGB-DIERHU-E.js → timeline-definition-JXYKGLGB-CTeYEw-9.js} +2 -2
- package/dist/assets/assets/{treeView-D4JQ5SDB-FzOWPt9M.js → treeView-D4JQ5SDB-DD-EsLLT.js} +1 -1
- package/dist/assets/assets/{treemap-SAJKECNS-CegfZQHL.js → treemap-SAJKECNS-BLdFeS5J.js} +1 -1
- package/dist/assets/assets/{usecaseDiagram-WPOLBNNX-D_rAh-Gx.js → usecaseDiagram-WPOLBNNX-C1GikSSP.js} +2 -2
- package/dist/assets/assets/{vennDiagram-Q3Y3IDCW-D_Jk9J88.js → vennDiagram-Q3Y3IDCW-B1FoA3g8.js} +2 -2
- package/dist/assets/assets/{wardley-7MLQ67FV-DIEbQxJ2.js → wardley-7MLQ67FV-BrHb5Bjf.js} +1 -1
- package/dist/assets/assets/{wardleyDiagram-IVAIDKWA-CXqJq4I3.js → wardleyDiagram-IVAIDKWA-CmPLD1X4.js} +2 -2
- package/dist/assets/assets/{webpack-DGVItmjq.js → webpack-BYWDFj_R.js} +2 -2
- package/dist/assets/assets/{xychartDiagram-4URNHDU4-CMxXwkRY.js → xychartDiagram-4URNHDU4-DR5pfEjl.js} +2 -2
- package/dist/assets/bundle-asset-policy.json +1 -1
- package/dist/assets/index.html +1 -1
- package/dist/{atomicJson-CGwDUowZ.js → atomicJson-BJfPFSYF.js} +3 -3
- package/dist/{codemode-TQ9j-uu8.js → codemode-DbPu0yJN.js} +1 -1
- package/dist/{domains-CHu4UHyM.js → domains-BNjGTOPj.js} +4 -4
- package/dist/{exports-gUrOdCGe.js → exports-BNZz2DNU.js} +8 -8
- package/dist/{extensionFile-y7HgkPJE.js → extensionFile-CXOa5G4C.js} +1 -1
- package/dist/{harnessStore-BoAsqzlV.js → harnessStore-BT706Ly6.js} +4 -4
- package/dist/harnessStore-BiH9vSuD.js +1 -0
- package/dist/{hubChannel-CtOHrMyS.js → hubChannel-BHQyzcOo.js} +1 -1
- package/dist/{layeredConfig-CNvjRTVo.js → layeredConfig-DPQAnlXD.js} +3 -3
- package/dist/majorModes-BvWNqoHt.js +1 -0
- package/dist/{majorModes-Xmq_LGoe.js → majorModes-DbCfLZH3.js} +4 -4
- package/dist/{platform-zL5VIT0Q.js → platform-B4AAgwJ0.js} +1 -1
- package/dist/{platformFiles-C_UD_up5.js → platformFiles-C_bXo4Ig.js} +1 -1
- package/dist/{remoteMcp-gsUJtMH_.js → remoteMcp-CMqZldeA.js} +1 -1
- package/dist/{server-CMDtMXmj.js → server-36iuA3MI.js} +2 -2
- package/dist/{server-DFKKVmzR.js → server-A-_GFpPr.js} +6 -6
- package/dist/{server-MNqJU24k.js → server-BAAL9-NA.js} +2 -2
- package/dist/{server-DUTSyKgc.js → server-BE6VqEiA.js} +5 -5
- package/dist/{server-CG_9qNcb.js → server-BZaPPoQp.js} +9 -9
- package/dist/{server-bGuBoH_L.js → server-BZh1ZXz_.js} +4 -4
- package/dist/{server-KQnrM6NC.js → server-D3PQk1Gt.js} +15 -10
- package/dist/{server-raR8emni.js → server-D4W7EdJY.js} +9 -9
- package/dist/{server-PQEJtDPE.js → server-D75MWDhB.js} +2 -2
- package/dist/{server-X3fmuuiB.js → server-D8ndq0wL.js} +2 -2
- package/dist/{server-CW9vgXZZ.js → server-DJAanjoI.js} +7 -7
- package/dist/{server-B4TVo_HG.js → server-Dpgh8PDh.js} +4 -4
- package/dist/{server-C_rqzLpT.js → server-Dt4y1rZD.js} +5 -5
- package/dist/{server-BtzV4Ue5.js → server-r358hzQg.js} +3 -3
- package/dist/{server-ag7rCqRj.js → server-tvgQ99rv.js} +4 -4
- package/dist/{serverPlugin-CyB83fX5.js → serverPlugin-BOI6c6s5.js} +7 -7
- package/dist/{sessionConfig-DzWoFVFq.js → sessionConfig-rBQgzXlT.js} +8 -8
- package/dist/worker.js +11838 -7313
- package/package.json +25 -25
- package/dist/apiContracts-D62gD_Mj.js +0 -10002
- package/dist/assets/assets/channel-Dzg3u7Ic.js +0 -2
- package/dist/assets/assets/chunk-XXDRQBXY-g9Ew2afQ.js +0 -2
- package/dist/assets/assets/flowDiagram-IUGLLWBU-B4Wk_lLe.js +0 -1
- package/dist/assets/assets/index-VE9rBUgK.js +0 -157
- package/dist/assets/assets/swimlanesDiagram-AYQRV4AK-CP1AUteh.js +0 -9
- package/dist/harnessStore-CQTloy2K.js +0 -1
- package/dist/majorModes-EMtnftWr.js +0 -1
|
@@ -0,0 +1,4451 @@
|
|
|
1
|
+
import { A as Integer, C as Null, G as _Object_, M as Boolean, Q as _Array_, R as Intersect, U as Unknown, V as Unsafe, _ as Union, a as Partial, d as Record, h as Tuple, k as Literal, o as Omit, q as Optional$4, x as Number$1, y as String$1 } from "./build-2gFaVEfG.js";
|
|
2
|
+
import { n as Check } from "./value-Djvc2foV.js";
|
|
3
|
+
//#region ../../core/po-core/src/schemas/pluginProtocol.ts
|
|
4
|
+
/** The address is always exact. A workspace call never resolves to a global service. */
|
|
5
|
+
const PoPluginMountSchema = Union([
|
|
6
|
+
_Object_({ scope: Literal("global") }, { additionalProperties: false }),
|
|
7
|
+
_Object_({
|
|
8
|
+
scope: Literal("workspace"),
|
|
9
|
+
workspaceId: String$1({ minLength: 1 })
|
|
10
|
+
}, { additionalProperties: false }),
|
|
11
|
+
_Object_({
|
|
12
|
+
scope: Literal("session"),
|
|
13
|
+
sessionId: String$1({ minLength: 1 })
|
|
14
|
+
}, { additionalProperties: false })
|
|
15
|
+
]);
|
|
16
|
+
const PoPluginCallSchema = _Object_({
|
|
17
|
+
mount: PoPluginMountSchema,
|
|
18
|
+
service: String$1({ minLength: 1 }),
|
|
19
|
+
method: String$1({ minLength: 1 }),
|
|
20
|
+
input: Unknown()
|
|
21
|
+
}, { additionalProperties: false });
|
|
22
|
+
function definePoPluginMethod(definition) {
|
|
23
|
+
if (!definition.service || !definition.method) throw new Error("Plugin service and method must be named.");
|
|
24
|
+
return definition;
|
|
25
|
+
}
|
|
26
|
+
function poPluginMountKey(mount) {
|
|
27
|
+
if (!Check(PoPluginMountSchema, mount)) throw new Error("Invalid plugin mount.");
|
|
28
|
+
switch (mount.scope) {
|
|
29
|
+
case "global": return "global";
|
|
30
|
+
case "workspace": return `workspace:${mount.workspaceId}`;
|
|
31
|
+
case "session": return `session:${mount.sessionId}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
var PoPluginCallError = class extends Error {
|
|
35
|
+
code;
|
|
36
|
+
constructor(code, message) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.code = code;
|
|
39
|
+
this.name = "PoPluginCallError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/** Transport-neutral dispatch, shared by Chord server services and client capability hosts. */
|
|
43
|
+
function createPoPluginRegistry() {
|
|
44
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
45
|
+
let disposed = false;
|
|
46
|
+
const keyOf = (mount, service, method, direction) => `${poPluginMountKey(mount)}\0${direction}\0${service}\0${method}`;
|
|
47
|
+
return {
|
|
48
|
+
register(mount, definition, handler) {
|
|
49
|
+
if (disposed) throw new Error("Plugin registry is disposed.");
|
|
50
|
+
if (mount.scope !== definition.scope) throw new Error(`Method '${definition.service}.${definition.method}' requires ${definition.scope} scope.`);
|
|
51
|
+
const key = keyOf(mount, definition.service, definition.method, definition.direction);
|
|
52
|
+
if (handlers.has(key)) throw new Error(`Plugin method '${definition.service}.${definition.method}' is already mounted.`);
|
|
53
|
+
const entry = {
|
|
54
|
+
definition,
|
|
55
|
+
handler
|
|
56
|
+
};
|
|
57
|
+
handlers.set(key, entry);
|
|
58
|
+
return () => {
|
|
59
|
+
if (handlers.get(key) === entry) handlers.delete(key);
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
async invoke(value, direction, caller = {}) {
|
|
63
|
+
if (disposed) throw new Error("Plugin registry is disposed.");
|
|
64
|
+
if (!Check(PoPluginCallSchema, value)) throw new PoPluginCallError("INVALID_CALL", "Invalid plugin call.");
|
|
65
|
+
const call = value;
|
|
66
|
+
const entry = handlers.get(keyOf(call.mount, call.service, call.method, direction));
|
|
67
|
+
if (!entry) throw new PoPluginCallError("METHOD_NOT_FOUND", `Plugin method '${call.service}.${call.method}' is not mounted at this scope.`);
|
|
68
|
+
if (!Check(entry.definition.input, call.input)) throw new PoPluginCallError("INVALID_INPUT", `Invalid input for '${call.service}.${call.method}'.`);
|
|
69
|
+
const output = await entry.handler(call.input, caller);
|
|
70
|
+
if (!Check(entry.definition.output, output)) throw new PoPluginCallError("INVALID_OUTPUT", `Invalid output from '${call.service}.${call.method}'.`);
|
|
71
|
+
return output;
|
|
72
|
+
},
|
|
73
|
+
dispose() {
|
|
74
|
+
disposed = true;
|
|
75
|
+
handlers.clear();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/builders.js
|
|
81
|
+
/** A string, with optional length bounds (in code points), pattern and format. */
|
|
82
|
+
function str(options = {}) {
|
|
83
|
+
return {
|
|
84
|
+
type: "string",
|
|
85
|
+
...options
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** A number within optional bounds. */
|
|
89
|
+
function num(options = {}) {
|
|
90
|
+
return {
|
|
91
|
+
type: "number",
|
|
92
|
+
...options
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** An integer within optional bounds. */
|
|
96
|
+
function int(options = {}) {
|
|
97
|
+
return {
|
|
98
|
+
type: "integer",
|
|
99
|
+
...options
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** A boolean. */
|
|
103
|
+
function bool(options = {}) {
|
|
104
|
+
return {
|
|
105
|
+
type: "boolean",
|
|
106
|
+
...options
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/** Any value. */
|
|
110
|
+
function unknown(options = {}) {
|
|
111
|
+
return { ...options };
|
|
112
|
+
}
|
|
113
|
+
/** Exactly `value` (a string, number, boolean or null). */
|
|
114
|
+
function lit(value, options = {}) {
|
|
115
|
+
return {
|
|
116
|
+
const: value,
|
|
117
|
+
...options
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** One of the given values. */
|
|
121
|
+
function oneOf(values, options = {}) {
|
|
122
|
+
return {
|
|
123
|
+
enum: values,
|
|
124
|
+
...options
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Any of the given schemas. A union of objects tagged by a `lit()` property (`{ kind: lit("text"), ... }`) is checked
|
|
129
|
+
* by the tag: only the branch it selects runs, and its errors are the ones reported.
|
|
130
|
+
*/
|
|
131
|
+
function union(schemas, options = {}) {
|
|
132
|
+
return {
|
|
133
|
+
anyOf: schemas,
|
|
134
|
+
...options
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** An array of `items`, with optional length bounds and unique items. */
|
|
138
|
+
function arr(items, options = {}) {
|
|
139
|
+
return {
|
|
140
|
+
type: "array",
|
|
141
|
+
items,
|
|
142
|
+
...options
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** An object with string keys and values of `value` (a record). */
|
|
146
|
+
function map(value, options = {}) {
|
|
147
|
+
return {
|
|
148
|
+
type: "object",
|
|
149
|
+
additionalProperties: value,
|
|
150
|
+
...options
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/** An optional property of obj(): `{ name: opt(str()) }` may omit `name` or set it to undefined. */
|
|
154
|
+
var Optional$3 = class {
|
|
155
|
+
schema;
|
|
156
|
+
constructor(schema) {
|
|
157
|
+
this.schema = schema;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
/** Marks an obj() property as optional. */
|
|
161
|
+
function opt(schema) {
|
|
162
|
+
return new Optional$3(schema);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A closed object: the given properties (required unless opt()) and no others. `open: true` allows other
|
|
166
|
+
* properties, as tool schemas from other systems often do.
|
|
167
|
+
*/
|
|
168
|
+
function obj(properties, options = {}) {
|
|
169
|
+
const { open, ...annotations } = options;
|
|
170
|
+
const props = {};
|
|
171
|
+
const required = [];
|
|
172
|
+
for (const [name, property] of Object.entries(properties)) if (property instanceof Optional$3) props[name] = property.schema;
|
|
173
|
+
else {
|
|
174
|
+
props[name] = property;
|
|
175
|
+
required.push(name);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
type: "object",
|
|
179
|
+
properties: props,
|
|
180
|
+
...required.length > 0 ? { required } : {},
|
|
181
|
+
...open === true ? {} : { additionalProperties: false },
|
|
182
|
+
...annotations
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/resolver.js
|
|
187
|
+
/** The base URI of a root schema without `$id`; relative references resolve against it. */
|
|
188
|
+
const DEFAULT_BASE = "https://json-schema.invalid/root.json";
|
|
189
|
+
/**
|
|
190
|
+
* Resolves references in the root schema and the registered documents. The schema is indexed on the first
|
|
191
|
+
* reference, so a schema without references is never walked for identifiers.
|
|
192
|
+
*/
|
|
193
|
+
var Resolver = class {
|
|
194
|
+
draft;
|
|
195
|
+
rootBase;
|
|
196
|
+
/** Schema object to the base URI it was indexed under. */
|
|
197
|
+
baseOf = /* @__PURE__ */ new Map();
|
|
198
|
+
/** URI (with a `#name` fragment) of every `$dynamicAnchor`, to its schema. */
|
|
199
|
+
dynamicAnchors = /* @__PURE__ */ new Map();
|
|
200
|
+
root;
|
|
201
|
+
options;
|
|
202
|
+
registry = /* @__PURE__ */ new Map();
|
|
203
|
+
rejectUnresolved;
|
|
204
|
+
/** The references that named nothing and resolved to `false` (with `unresolvedRefs: "reject"`). */
|
|
205
|
+
unresolved = /* @__PURE__ */ new Set();
|
|
206
|
+
resources = /* @__PURE__ */ new Map();
|
|
207
|
+
anchors = /* @__PURE__ */ new Map();
|
|
208
|
+
indexed = false;
|
|
209
|
+
constructor(root, options) {
|
|
210
|
+
this.draft = options.draft === "7" ? "7" : "2020-12";
|
|
211
|
+
this.root = root;
|
|
212
|
+
this.options = options;
|
|
213
|
+
this.rejectUnresolved = options.unresolvedRefs === "reject";
|
|
214
|
+
this.rootBase = isSchemaObject$1(root) ? this.baseFor(root, DEFAULT_BASE) : DEFAULT_BASE;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* The base URI of `node`, whose parent has `base`: its `$id` changes it, unless draft 7 makes the `$id` inert. Once
|
|
218
|
+
* the schema is indexed, the indexed base (a resolved reference target already has its own).
|
|
219
|
+
*/
|
|
220
|
+
baseFor(node, base) {
|
|
221
|
+
const indexed = this.baseOf.get(node);
|
|
222
|
+
if (indexed !== void 0) return indexed;
|
|
223
|
+
const id = node.$id;
|
|
224
|
+
if (typeof id !== "string") return base;
|
|
225
|
+
if (this.draft === "7" && (typeof node.$ref === "string" || id.startsWith("#"))) return base;
|
|
226
|
+
return documentOf(resolveUri(id, base));
|
|
227
|
+
}
|
|
228
|
+
/** Indexes the root schema and the registered documents' URIs (once). */
|
|
229
|
+
ensureIndexed() {
|
|
230
|
+
if (this.indexed) return;
|
|
231
|
+
this.indexed = true;
|
|
232
|
+
for (const [uri, schema] of Object.entries(this.options.schemas ?? {})) this.registry.set(documentOf(resolveUri(uri, DEFAULT_BASE)), schema);
|
|
233
|
+
this.resources.set(DEFAULT_BASE, this.root);
|
|
234
|
+
this.index(this.root, DEFAULT_BASE);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The schema a reference names, with the base URI it compiles under. Throws if it names nothing, or, with
|
|
238
|
+
* `unresolvedRefs: "reject"`, resolves to `false`, the schema no value passes.
|
|
239
|
+
*/
|
|
240
|
+
resolve(ref, base) {
|
|
241
|
+
this.ensureIndexed();
|
|
242
|
+
if (!this.rejectUnresolved) return this.find(ref, base);
|
|
243
|
+
try {
|
|
244
|
+
return this.find(ref, base);
|
|
245
|
+
} catch {
|
|
246
|
+
this.unresolved.add(resolveUri(ref, base));
|
|
247
|
+
return {
|
|
248
|
+
node: false,
|
|
249
|
+
base
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/** Whether `ref`, from `base`, named nothing and resolved to `false`. */
|
|
254
|
+
isUnresolved(ref, base) {
|
|
255
|
+
return this.unresolved.has(resolveUri(ref, base));
|
|
256
|
+
}
|
|
257
|
+
find(ref, base) {
|
|
258
|
+
const uri = resolveUri(ref, base);
|
|
259
|
+
const doc = documentOf(uri);
|
|
260
|
+
const fragment = uri.length > doc.length ? decodeURIComponent(uri.slice(doc.length + 1)) : "";
|
|
261
|
+
const root = this.resources.has(doc) ? this.resources.get(doc) : this.load(doc);
|
|
262
|
+
if (root === void 0) throw new Error(`Unresolved $ref ${ref} (no schema registered for ${doc})`);
|
|
263
|
+
if (fragment === "") return {
|
|
264
|
+
node: root,
|
|
265
|
+
base: doc
|
|
266
|
+
};
|
|
267
|
+
if (fragment.startsWith("/")) return this.pointer(root, doc, fragment);
|
|
268
|
+
const target = this.anchors.get(`${doc}#${fragment}`);
|
|
269
|
+
if (target === void 0) throw new Error(`Unresolved $ref ${ref} (no anchor ${fragment} in ${doc})`);
|
|
270
|
+
return {
|
|
271
|
+
node: target,
|
|
272
|
+
base: this.baseOf.get(target) ?? doc
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/** Whether `node` is the root of the schema resource at `base`. */
|
|
276
|
+
isResource(node, base) {
|
|
277
|
+
this.ensureIndexed();
|
|
278
|
+
return this.resources.get(base) === node;
|
|
279
|
+
}
|
|
280
|
+
index(node, base) {
|
|
281
|
+
if (!isSchemaObject$1(node) || this.baseOf.has(node)) return;
|
|
282
|
+
let b = base;
|
|
283
|
+
const refOnly = this.draft === "7" && typeof node.$ref === "string";
|
|
284
|
+
if (!refOnly && typeof node.$id === "string") {
|
|
285
|
+
if (this.draft === "7" && node.$id.startsWith("#")) this.anchors.set(documentOf(b) + node.$id, node);
|
|
286
|
+
else {
|
|
287
|
+
const uri = resolveUri(node.$id, b);
|
|
288
|
+
b = documentOf(uri);
|
|
289
|
+
this.resources.set(b, node);
|
|
290
|
+
if (uri.length > b.length + 1) this.anchors.set(uri, node);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
this.baseOf.set(node, b);
|
|
294
|
+
if (refOnly) return;
|
|
295
|
+
if (this.draft !== "7") {
|
|
296
|
+
if (typeof node.$anchor === "string") this.anchors.set(`${b}#${node.$anchor}`, node);
|
|
297
|
+
if (typeof node.$dynamicAnchor === "string") {
|
|
298
|
+
this.anchors.set(`${b}#${node.$dynamicAnchor}`, node);
|
|
299
|
+
this.dynamicAnchors.set(`${b}#${node.$dynamicAnchor}`, node);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
for (const key of SCHEMA_KEYWORDS) this.index(node[key], b);
|
|
303
|
+
for (const key of MAP_KEYWORDS) {
|
|
304
|
+
const map = node[key];
|
|
305
|
+
if (isSchemaObject$1(map)) for (const k of Object.keys(map)) this.index(map[k], b);
|
|
306
|
+
}
|
|
307
|
+
for (const key of ARRAY_KEYWORDS) {
|
|
308
|
+
const list = node[key];
|
|
309
|
+
if (Array.isArray(list)) for (const s of list) this.index(s, b);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
load(doc) {
|
|
313
|
+
const schema = this.registry.get(doc);
|
|
314
|
+
if (schema === void 0) return void 0;
|
|
315
|
+
this.resources.set(doc, schema);
|
|
316
|
+
this.index(schema, doc);
|
|
317
|
+
return schema;
|
|
318
|
+
}
|
|
319
|
+
pointer(root, base, fragment) {
|
|
320
|
+
let node = root;
|
|
321
|
+
let b = base;
|
|
322
|
+
for (const raw of fragment.split("/").slice(1)) {
|
|
323
|
+
const key = raw.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
324
|
+
node = typeof node === "object" && node !== null && Object.hasOwn(node, key) ? node[key] : void 0;
|
|
325
|
+
if (node === void 0) throw new Error(`Unresolved $ref #${fragment} in ${base}`);
|
|
326
|
+
if (typeof node === "object" && node !== null) b = this.baseOf.get(node) ?? b;
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
node,
|
|
330
|
+
base: b
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
const SCHEMA_KEYWORDS = [
|
|
335
|
+
"additionalProperties",
|
|
336
|
+
"propertyNames",
|
|
337
|
+
"contains",
|
|
338
|
+
"not",
|
|
339
|
+
"if",
|
|
340
|
+
"then",
|
|
341
|
+
"else",
|
|
342
|
+
"unevaluatedProperties",
|
|
343
|
+
"unevaluatedItems",
|
|
344
|
+
"additionalItems",
|
|
345
|
+
"contentSchema",
|
|
346
|
+
"items"
|
|
347
|
+
];
|
|
348
|
+
const MAP_KEYWORDS = [
|
|
349
|
+
"properties",
|
|
350
|
+
"patternProperties",
|
|
351
|
+
"$defs",
|
|
352
|
+
"definitions",
|
|
353
|
+
"dependentSchemas",
|
|
354
|
+
"dependencies"
|
|
355
|
+
];
|
|
356
|
+
const ARRAY_KEYWORDS = [
|
|
357
|
+
"allOf",
|
|
358
|
+
"anyOf",
|
|
359
|
+
"oneOf",
|
|
360
|
+
"prefixItems",
|
|
361
|
+
"items"
|
|
362
|
+
];
|
|
363
|
+
/** Whether `value` is a schema object (not `true`/`false`, an array or a primitive). */
|
|
364
|
+
function isSchemaObject$1(value) {
|
|
365
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
366
|
+
}
|
|
367
|
+
/** `ref` resolved against `base`. URNs and other bases a URL parser rejects take fragment-only references. */
|
|
368
|
+
function resolveUri(ref, base) {
|
|
369
|
+
try {
|
|
370
|
+
return new URL(ref, base).href;
|
|
371
|
+
} catch {
|
|
372
|
+
return ref.startsWith("#") ? documentOf(base) + ref : ref;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/** `uri` without its fragment. */
|
|
376
|
+
function documentOf(uri) {
|
|
377
|
+
const hash = uri.indexOf("#");
|
|
378
|
+
return hash < 0 ? uri : uri.slice(0, hash);
|
|
379
|
+
}
|
|
380
|
+
//#endregion
|
|
381
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/shared.js
|
|
382
|
+
/**
|
|
383
|
+
* The regular expression of a `pattern` source, shared by source. Patterns are ECMAScript regular expressions with
|
|
384
|
+
* the `u` flag; a source that is invalid with it (some older schemas escape characters `u` rejects) compiles
|
|
385
|
+
* without it.
|
|
386
|
+
*/
|
|
387
|
+
function sharedRegex(source) {
|
|
388
|
+
const hit = regexes.get(source)?.deref();
|
|
389
|
+
if (hit !== void 0) return hit;
|
|
390
|
+
let re;
|
|
391
|
+
try {
|
|
392
|
+
re = new RegExp(source, "u");
|
|
393
|
+
} catch {
|
|
394
|
+
re = new RegExp(source);
|
|
395
|
+
}
|
|
396
|
+
regexes.set(source, new WeakRef(re));
|
|
397
|
+
regexCleanup.register(re, source);
|
|
398
|
+
return re;
|
|
399
|
+
}
|
|
400
|
+
const regexes = /* @__PURE__ */ new Map();
|
|
401
|
+
const regexCleanup = new FinalizationRegistry((source) => {
|
|
402
|
+
if (regexes.get(source)?.deref() === void 0) regexes.delete(source);
|
|
403
|
+
});
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/coerce.js
|
|
406
|
+
/** Coerces values for one compiled schema. */
|
|
407
|
+
var Coercer = class {
|
|
408
|
+
c;
|
|
409
|
+
schema;
|
|
410
|
+
/**
|
|
411
|
+
* The (schema node, value) pairs pass 2 is converting through a re-entry point, as a stack. Conversion can enter
|
|
412
|
+
* a node again with the same value only through a `$ref` or by wrapping a single value into an array (also for
|
|
413
|
+
* schemas that cycle through shared JS objects): a recursive schema that meets a value no branch accepts would
|
|
414
|
+
* convert it without end. A pair already on the stack (primitives by value, objects by reference) leaves the value
|
|
415
|
+
* unchanged. Only those two points push, so schemas without references or wraps pay nothing.
|
|
416
|
+
*/
|
|
417
|
+
entered = [];
|
|
418
|
+
/** How often a re-entry was cut short in this coerce() call; results computed across one are not memoized. */
|
|
419
|
+
cuts = 0;
|
|
420
|
+
/**
|
|
421
|
+
* Results of `$ref` targets by (node, value) within one coerce() call: a recursive union whose branches all
|
|
422
|
+
* convert the same children (and all fail) would convert them once per branch, exponentially in the depth.
|
|
423
|
+
*/
|
|
424
|
+
memo = void 0;
|
|
425
|
+
constructor(compiler, schema) {
|
|
426
|
+
this.c = compiler;
|
|
427
|
+
this.schema = schema;
|
|
428
|
+
}
|
|
429
|
+
/** `value` coerced: a copy along the changed paths only, or `value` itself when nothing changes. */
|
|
430
|
+
coerce(value) {
|
|
431
|
+
const base = this.c.r.rootBase;
|
|
432
|
+
const withoutNulls = this.dropOptionalNulls(value, this.schema, base);
|
|
433
|
+
return this.coerceTypes(this.convertOnly(withoutNulls), this.schema, base);
|
|
434
|
+
}
|
|
435
|
+
/** Pass 2 alone, as TypeBox's `Value.Convert` (the TypeBox conformance tests run it). */
|
|
436
|
+
convertOnly(value) {
|
|
437
|
+
try {
|
|
438
|
+
return this.convert(this.schema, this.c.r.rootBase, value);
|
|
439
|
+
} finally {
|
|
440
|
+
this.memo = void 0;
|
|
441
|
+
this.cuts = 0;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/** `node` converted for `value` at a re-entry point: unchanged when that pair is already being converted. */
|
|
445
|
+
reenter(node, base, value, memoize) {
|
|
446
|
+
const entered = this.entered;
|
|
447
|
+
for (let i = 0; i < entered.length; i += 2) if (entered[i] === node && Object.is(entered[i + 1], value)) {
|
|
448
|
+
this.cuts++;
|
|
449
|
+
return value;
|
|
450
|
+
}
|
|
451
|
+
const memo = memoize ? this.memo?.get(node) : void 0;
|
|
452
|
+
if (memo?.has(value)) return memo.get(value);
|
|
453
|
+
const cuts = this.cuts;
|
|
454
|
+
entered.push(node, value);
|
|
455
|
+
let result;
|
|
456
|
+
try {
|
|
457
|
+
result = this.convert(node, base, value);
|
|
458
|
+
} finally {
|
|
459
|
+
entered.length -= 2;
|
|
460
|
+
}
|
|
461
|
+
if (memoize && this.cuts === cuts) {
|
|
462
|
+
this.memo ??= /* @__PURE__ */ new Map();
|
|
463
|
+
let values = this.memo.get(node);
|
|
464
|
+
if (values === void 0) {
|
|
465
|
+
values = /* @__PURE__ */ new Map();
|
|
466
|
+
this.memo.set(node, values);
|
|
467
|
+
}
|
|
468
|
+
values.set(value, result);
|
|
469
|
+
}
|
|
470
|
+
return result;
|
|
471
|
+
}
|
|
472
|
+
/** Whether `value` passes the schema `node`; undefined when `node` cannot be compiled. */
|
|
473
|
+
passes(node, base, value) {
|
|
474
|
+
try {
|
|
475
|
+
return this.c.check(node, this.baseOf(node, base))(value);
|
|
476
|
+
} catch {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
baseOf(node, base) {
|
|
481
|
+
return isSchemaObject$1(node) ? this.c.r.baseOf.get(node) ?? base : base;
|
|
482
|
+
}
|
|
483
|
+
dropOptionalNulls(value, schema, base) {
|
|
484
|
+
if (!isSchemaObject$1(schema)) return value;
|
|
485
|
+
const b = this.baseOf(schema, base);
|
|
486
|
+
if (Array.isArray(value)) return mapItems(value, (item, i) => {
|
|
487
|
+
const itemSchema = itemSchemaAt(schema, i);
|
|
488
|
+
return itemSchema === void 0 ? item : this.dropOptionalNulls(item, itemSchema, b);
|
|
489
|
+
});
|
|
490
|
+
if (!isPlainObject$1(value)) return value;
|
|
491
|
+
const properties = isSchemaObject$1(schema.properties) ? schema.properties : {};
|
|
492
|
+
const patterns = isSchemaObject$1(schema.patternProperties) ? Object.entries(schema.patternProperties).map(([pattern, item]) => [sharedRegex(pattern), item]) : [];
|
|
493
|
+
const additional = isSchemaObject$1(schema.additionalProperties) ? schema.additionalProperties : void 0;
|
|
494
|
+
if (patterns.length === 0 && additional === void 0 && !isSchemaObject$1(schema.properties)) return value;
|
|
495
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
496
|
+
let out;
|
|
497
|
+
const set = (key, next) => {
|
|
498
|
+
if (next === (out ?? value)[key]) return;
|
|
499
|
+
out ??= { ...value };
|
|
500
|
+
out[key] = next;
|
|
501
|
+
};
|
|
502
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
503
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
504
|
+
const isRef = isSchemaObject$1(property) && typeof property.$ref === "string";
|
|
505
|
+
if (value[key] === null && !required.has(key) && !isRef && this.passes(property, b, null) === false) {
|
|
506
|
+
out ??= { ...value };
|
|
507
|
+
delete out[key];
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
set(key, this.dropOptionalNulls(value[key], property, b));
|
|
511
|
+
}
|
|
512
|
+
if (patterns.length > 0 || additional !== void 0) for (const key of Object.keys(value)) {
|
|
513
|
+
let matched = Object.hasOwn(properties, key);
|
|
514
|
+
for (const [pattern, item] of patterns) {
|
|
515
|
+
if (!pattern.test(key)) continue;
|
|
516
|
+
matched = true;
|
|
517
|
+
set(key, this.dropOptionalNulls((out ?? value)[key], item, b));
|
|
518
|
+
}
|
|
519
|
+
if (!matched && additional !== void 0) set(key, this.dropOptionalNulls(value[key], additional, b));
|
|
520
|
+
}
|
|
521
|
+
return out ?? value;
|
|
522
|
+
}
|
|
523
|
+
convert(node, base, value) {
|
|
524
|
+
if (!isSchemaObject$1(node)) return value;
|
|
525
|
+
const b = this.baseOf(node, base);
|
|
526
|
+
if (typeof node.$ref === "string") {
|
|
527
|
+
let target;
|
|
528
|
+
try {
|
|
529
|
+
target = this.c.r.resolve(node.$ref, b);
|
|
530
|
+
} catch {
|
|
531
|
+
return value;
|
|
532
|
+
}
|
|
533
|
+
return isSchemaObject$1(target.node) ? this.reenter(target.node, target.base, value, true) : value;
|
|
534
|
+
}
|
|
535
|
+
return this.convertNode(node, b, value);
|
|
536
|
+
}
|
|
537
|
+
/** One schema node's conversion: its first keyword among `const`, `enum`, the unions, `allOf` and `type`. */
|
|
538
|
+
convertNode(node, b, value) {
|
|
539
|
+
if (Object.hasOwn(node, "const")) return convertLiteral(node.const, value);
|
|
540
|
+
if (Array.isArray(node.enum)) return this.convertEnum(node, node.enum, b, value);
|
|
541
|
+
if (Array.isArray(node.anyOf)) return this.convertUnion(node, node.anyOf, b, value);
|
|
542
|
+
if (Array.isArray(node.oneOf)) return this.convertUnion(node, node.oneOf, b, value);
|
|
543
|
+
if (Array.isArray(node.allOf)) {
|
|
544
|
+
let next = value;
|
|
545
|
+
for (const member of node.allOf) next = this.convert(member, b, next);
|
|
546
|
+
return this.convertMembers(node, b, next);
|
|
547
|
+
}
|
|
548
|
+
switch (node.type) {
|
|
549
|
+
case "string": return orValue(tryString(value), value);
|
|
550
|
+
case "number": return orValue(tryNumber(value), value);
|
|
551
|
+
case "integer": {
|
|
552
|
+
const result = tryNumber(value);
|
|
553
|
+
return result === void 0 ? value : Math.trunc(result.value);
|
|
554
|
+
}
|
|
555
|
+
case "boolean": return orValue(tryBoolean(value), value);
|
|
556
|
+
case "null": return orValue(tryNull(value), value);
|
|
557
|
+
case "array": return this.convertArray(node, b, value);
|
|
558
|
+
case "object": return this.convertObject(node, b, value);
|
|
559
|
+
case void 0:
|
|
560
|
+
if (node.properties !== void 0 || node.patternProperties !== void 0) return this.convertObject(node, b, value);
|
|
561
|
+
if (node.items !== void 0 || node.prefixItems !== void 0) return this.convertArray(node, b, value);
|
|
562
|
+
return value;
|
|
563
|
+
default: return value;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
/** An enum is a union of its values: a member stays, else the first value the input converts to. */
|
|
567
|
+
convertEnum(node, values, base, value) {
|
|
568
|
+
if (values.some((member) => member === value)) return value;
|
|
569
|
+
for (const member of values) {
|
|
570
|
+
const candidate = convertLiteral(member, value);
|
|
571
|
+
if (candidate !== value && this.passes(node, base, candidate) === true) return candidate;
|
|
572
|
+
}
|
|
573
|
+
return value;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* A value one branch accepts stays; else the first branch's conversion that the whole union accepts. Branches are
|
|
577
|
+
* converted in order and only until one is accepted, so a later recursive branch is not entered needlessly. A node
|
|
578
|
+
* that also declares members (plain JSON Schema; TypeBox's never do) converts them into each candidate before it is
|
|
579
|
+
* checked, so a branch is not discarded for a sibling property that is converted after it.
|
|
580
|
+
*/
|
|
581
|
+
convertUnion(node, branches, base, value) {
|
|
582
|
+
if (branches.some((branch) => this.passes(branch, base, value) === true)) return this.convertMembers(node, base, value);
|
|
583
|
+
for (const branch of branches) {
|
|
584
|
+
const candidate = this.convertMembers(node, base, this.convert(branch, base, value));
|
|
585
|
+
if (this.passes(node, base, candidate) === true) return candidate;
|
|
586
|
+
}
|
|
587
|
+
return this.convertMembers(node, base, value);
|
|
588
|
+
}
|
|
589
|
+
/** The object members of a union or intersection node, when it declares any. */
|
|
590
|
+
convertMembers(node, base, value) {
|
|
591
|
+
return node.properties !== void 0 || node.patternProperties !== void 0 || node.additionalProperties !== void 0 ? this.convertObject(node, base, value) : value;
|
|
592
|
+
}
|
|
593
|
+
convertArray(node, base, value) {
|
|
594
|
+
const prefix = Array.isArray(node.items) ? node.items : Array.isArray(node.prefixItems) ? node.prefixItems : void 0;
|
|
595
|
+
if (prefix !== void 0) {
|
|
596
|
+
if (!Array.isArray(value)) return value;
|
|
597
|
+
const rest = Array.isArray(node.items) ? void 0 : node.items;
|
|
598
|
+
return mapItems(value, (item, i) => {
|
|
599
|
+
const schema = i < prefix.length ? prefix[i] : rest;
|
|
600
|
+
return schema === void 0 ? item : this.convert(schema, base, item);
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
if (Array.isArray(value)) return node.items === void 0 ? value : mapItems(value, (item) => this.convert(node.items, base, item));
|
|
604
|
+
const item = node.items;
|
|
605
|
+
return [isSchemaObject$1(item) ? this.reenter(item, base, value, false) : value];
|
|
606
|
+
}
|
|
607
|
+
convertObject(node, base, value) {
|
|
608
|
+
if (!isPlainObject$1(value)) return value;
|
|
609
|
+
const properties = isSchemaObject$1(node.properties) ? node.properties : {};
|
|
610
|
+
const patterns = isSchemaObject$1(node.patternProperties) ? Object.entries(node.patternProperties).map(([pattern, schema]) => [sharedRegex(pattern), schema]) : [];
|
|
611
|
+
const additional = isSchemaObject$1(node.additionalProperties) ? node.additionalProperties : void 0;
|
|
612
|
+
let out;
|
|
613
|
+
for (const key of Object.keys(value)) {
|
|
614
|
+
if (value[key] === void 0) continue;
|
|
615
|
+
let next = value[key];
|
|
616
|
+
let matched = Object.hasOwn(properties, key);
|
|
617
|
+
if (matched) next = this.convert(properties[key], base, next);
|
|
618
|
+
for (const [pattern, schema] of patterns) {
|
|
619
|
+
if (!pattern.test(key)) continue;
|
|
620
|
+
matched = true;
|
|
621
|
+
next = this.convert(schema, base, next);
|
|
622
|
+
}
|
|
623
|
+
if (!matched && additional !== void 0) next = this.convert(additional, base, next);
|
|
624
|
+
if (next !== value[key]) {
|
|
625
|
+
out ??= { ...value };
|
|
626
|
+
out[key] = next;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return out ?? value;
|
|
630
|
+
}
|
|
631
|
+
coerceTypes(value, schema, base) {
|
|
632
|
+
if (!isSchemaObject$1(schema)) return value;
|
|
633
|
+
const b = this.baseOf(schema, base);
|
|
634
|
+
let next = value;
|
|
635
|
+
if (Array.isArray(schema.allOf)) for (const member of schema.allOf) next = this.coerceTypes(next, member, b);
|
|
636
|
+
if (Array.isArray(schema.anyOf)) next = this.coerceUnion(next, schema.anyOf, b);
|
|
637
|
+
if (Array.isArray(schema.oneOf)) next = this.coerceUnion(next, schema.oneOf, b);
|
|
638
|
+
const types = typesOf$1(schema);
|
|
639
|
+
const matchesUnionMember = types.length > 1 && types.some((type) => matchesType(next, type));
|
|
640
|
+
if (types.length > 0 && !matchesUnionMember) for (const type of types) {
|
|
641
|
+
const candidate = coercePrimitive(next, type);
|
|
642
|
+
if (candidate !== next) {
|
|
643
|
+
next = candidate;
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (types.includes("object") && isPlainObject$1(next)) next = this.coerceProperties(next, schema, b);
|
|
648
|
+
if (types.includes("array") && Array.isArray(next)) next = this.coerceItems(next, schema, b);
|
|
649
|
+
return next;
|
|
650
|
+
}
|
|
651
|
+
coerceUnion(value, branches, base) {
|
|
652
|
+
for (const branch of branches) if (this.passes(branch, base, value) === true) return value;
|
|
653
|
+
for (const branch of branches) {
|
|
654
|
+
const coerced = this.coerceTypes(value, branch, base);
|
|
655
|
+
if (this.passes(branch, base, coerced) === true) return coerced;
|
|
656
|
+
}
|
|
657
|
+
return value;
|
|
658
|
+
}
|
|
659
|
+
coerceProperties(value, schema, base) {
|
|
660
|
+
const properties = isSchemaObject$1(schema.properties) ? schema.properties : {};
|
|
661
|
+
const patterns = isSchemaObject$1(schema.patternProperties) ? Object.entries(schema.patternProperties).map(([pattern, item]) => [sharedRegex(pattern), item]) : [];
|
|
662
|
+
const additional = isSchemaObject$1(schema.additionalProperties) ? schema.additionalProperties : void 0;
|
|
663
|
+
let out;
|
|
664
|
+
const set = (key, next) => {
|
|
665
|
+
if (next === (out ?? value)[key]) return;
|
|
666
|
+
out ??= { ...value };
|
|
667
|
+
out[key] = next;
|
|
668
|
+
};
|
|
669
|
+
for (const [key, property] of Object.entries(properties)) if (key in value) set(key, this.coerceTypes(value[key], property, base));
|
|
670
|
+
for (const key of Object.keys(value)) {
|
|
671
|
+
let matched = Object.hasOwn(properties, key);
|
|
672
|
+
for (const [pattern, item] of patterns) {
|
|
673
|
+
if (!pattern.test(key)) continue;
|
|
674
|
+
matched = true;
|
|
675
|
+
set(key, this.coerceTypes((out ?? value)[key], item, base));
|
|
676
|
+
}
|
|
677
|
+
if (!matched && additional !== void 0) set(key, this.coerceTypes(value[key], additional, base));
|
|
678
|
+
}
|
|
679
|
+
return out ?? value;
|
|
680
|
+
}
|
|
681
|
+
coerceItems(value, schema, base) {
|
|
682
|
+
return mapItems(value, (item, i) => {
|
|
683
|
+
const itemSchema = itemSchemaAt(schema, i);
|
|
684
|
+
return isSchemaObject$1(itemSchema) ? this.coerceTypes(item, itemSchema, base) : item;
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
/**
|
|
689
|
+
* The schema of an array's item at `index`: a tuple's (`prefixItems`, or a draft-7 `items` array) for its prefix,
|
|
690
|
+
* `items` after `prefixItems`, or `items` for every item. Undefined when nothing applies.
|
|
691
|
+
*/
|
|
692
|
+
function itemSchemaAt(schema, index) {
|
|
693
|
+
if (Array.isArray(schema.items)) return schema.items[index];
|
|
694
|
+
if (Array.isArray(schema.prefixItems) && index < schema.prefixItems.length) return schema.prefixItems[index];
|
|
695
|
+
return schema.items;
|
|
696
|
+
}
|
|
697
|
+
/** `items` mapped by `map`; the same array when every item maps to itself. */
|
|
698
|
+
function mapItems(items, map) {
|
|
699
|
+
let out;
|
|
700
|
+
for (let i = 0; i < items.length; i++) {
|
|
701
|
+
const next = map(items[i], i);
|
|
702
|
+
if (next === items[i]) continue;
|
|
703
|
+
out ??= items.slice();
|
|
704
|
+
out[i] = next;
|
|
705
|
+
}
|
|
706
|
+
return out ?? items;
|
|
707
|
+
}
|
|
708
|
+
function orValue(result, value) {
|
|
709
|
+
return result === void 0 ? value : result.value;
|
|
710
|
+
}
|
|
711
|
+
/** A literal (`const`, an enum value) taken from a value of another type that converts to exactly it. */
|
|
712
|
+
function convertLiteral(literal, value) {
|
|
713
|
+
if (literal === value) return value;
|
|
714
|
+
const result = typeof literal === "string" ? tryString(value) : typeof literal === "number" ? tryNumber(value) : typeof literal === "boolean" ? tryBoolean(value) : void 0;
|
|
715
|
+
return result !== void 0 && result.value === literal ? result.value : value;
|
|
716
|
+
}
|
|
717
|
+
function tryString(value) {
|
|
718
|
+
if (typeof value === "bigint" || typeof value === "boolean" || isFiniteNumber(value)) return { value: String(value) };
|
|
719
|
+
if (value === null) return { value: "null" };
|
|
720
|
+
if (typeof value === "string") return { value };
|
|
721
|
+
if (value === void 0) return { value: "" };
|
|
722
|
+
}
|
|
723
|
+
const MAX_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
724
|
+
const MIN_BIGINT = BigInt(Number.MIN_SAFE_INTEGER);
|
|
725
|
+
function tryNumber(value) {
|
|
726
|
+
if (typeof value === "bigint") return value <= MAX_BIGINT && value >= MIN_BIGINT ? { value: Number(value) } : void 0;
|
|
727
|
+
if (typeof value === "boolean") return { value: value ? 1 : 0 };
|
|
728
|
+
if (isFiniteNumber(value)) return { value };
|
|
729
|
+
if (value === null || value === void 0) return { value: 0 };
|
|
730
|
+
if (typeof value !== "string") return void 0;
|
|
731
|
+
const coerced = +value;
|
|
732
|
+
if (Number.isFinite(coerced)) return { value: coerced };
|
|
733
|
+
const lowercase = value.toLowerCase();
|
|
734
|
+
if (lowercase === "false") return { value: 0 };
|
|
735
|
+
if (lowercase === "true") return { value: 1 };
|
|
736
|
+
const big = bigIntOfString(value);
|
|
737
|
+
return big !== void 0 && big <= MAX_BIGINT && big >= MIN_BIGINT ? { value: Number(big) } : void 0;
|
|
738
|
+
}
|
|
739
|
+
/** TypeBox's TryBigInt of a string: `12n`, `12.5` (truncated) or `12`; true and false are not reached from tryNumber. */
|
|
740
|
+
function bigIntOfString(value) {
|
|
741
|
+
if (/^-?(0|[1-9]\d*)n$/.test(value)) return BigInt(value.slice(0, -1));
|
|
742
|
+
if (/^-?(0|[1-9]\d*)\.\d+$/.test(value)) return BigInt(value.split(".")[0]);
|
|
743
|
+
if (/^-?(0|[1-9]\d*)$/.test(value)) return BigInt(value);
|
|
744
|
+
}
|
|
745
|
+
function tryBoolean(value) {
|
|
746
|
+
if (typeof value === "bigint") return value === 0n ? { value: false } : value === 1n ? { value: true } : void 0;
|
|
747
|
+
if (typeof value === "boolean") return { value };
|
|
748
|
+
if (isFiniteNumber(value)) return value === 0 ? { value: false } : value === 1 ? { value: true } : void 0;
|
|
749
|
+
if (value === null || value === void 0) return { value: false };
|
|
750
|
+
if (typeof value !== "string") return void 0;
|
|
751
|
+
const lowercase = value.toLowerCase();
|
|
752
|
+
if (lowercase === "false" || value === "0") return { value: false };
|
|
753
|
+
if (lowercase === "true" || value === "1") return { value: true };
|
|
754
|
+
}
|
|
755
|
+
function tryNull(value) {
|
|
756
|
+
if (typeof value === "bigint") return value === 0n ? { value: null } : void 0;
|
|
757
|
+
if (typeof value === "boolean") return value === false ? { value: null } : void 0;
|
|
758
|
+
if (isFiniteNumber(value)) return value === 0 ? { value: null } : void 0;
|
|
759
|
+
if (value === null || value === void 0) return { value: null };
|
|
760
|
+
if (typeof value !== "string") return void 0;
|
|
761
|
+
const lowercase = value.toLowerCase();
|
|
762
|
+
return lowercase === "undefined" || lowercase === "null" || value === "" || value === "0" ? { value: null } : void 0;
|
|
763
|
+
}
|
|
764
|
+
function isFiniteNumber(value) {
|
|
765
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
766
|
+
}
|
|
767
|
+
function typesOf$1(schema) {
|
|
768
|
+
if (typeof schema.type === "string") return [schema.type];
|
|
769
|
+
if (Array.isArray(schema.type)) return schema.type.filter((type) => typeof type === "string");
|
|
770
|
+
return [];
|
|
771
|
+
}
|
|
772
|
+
function matchesType(value, type) {
|
|
773
|
+
switch (type) {
|
|
774
|
+
case "number": return typeof value === "number";
|
|
775
|
+
case "integer": return typeof value === "number" && Number.isInteger(value);
|
|
776
|
+
case "boolean": return typeof value === "boolean";
|
|
777
|
+
case "string": return typeof value === "string";
|
|
778
|
+
case "null": return value === null;
|
|
779
|
+
case "array": return Array.isArray(value);
|
|
780
|
+
case "object": return isPlainObject$1(value);
|
|
781
|
+
default: return false;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
function coercePrimitive(value, type) {
|
|
785
|
+
switch (type) {
|
|
786
|
+
case "number":
|
|
787
|
+
case "integer":
|
|
788
|
+
if (value === null) return 0;
|
|
789
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
790
|
+
const parsed = Number(value);
|
|
791
|
+
if (type === "number" ? Number.isFinite(parsed) : Number.isInteger(parsed)) return parsed;
|
|
792
|
+
}
|
|
793
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
794
|
+
return value;
|
|
795
|
+
case "boolean":
|
|
796
|
+
if (value === null) return false;
|
|
797
|
+
if (value === "true" || value === 1) return true;
|
|
798
|
+
if (value === "false" || value === 0) return false;
|
|
799
|
+
return value;
|
|
800
|
+
case "string":
|
|
801
|
+
if (value === null) return "";
|
|
802
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
803
|
+
return value;
|
|
804
|
+
case "null": return value === "" || value === 0 || value === false ? null : value;
|
|
805
|
+
default: return value;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
function isPlainObject$1(value) {
|
|
809
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
810
|
+
}
|
|
811
|
+
//#endregion
|
|
812
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/checks.js
|
|
813
|
+
const ALWAYS = () => true;
|
|
814
|
+
const NEVER = () => false;
|
|
815
|
+
const IS_STRING = (v) => typeof v === "string";
|
|
816
|
+
const IS_NUMBER = (v) => typeof v === "number";
|
|
817
|
+
const IS_INTEGER = (v) => Number.isInteger(v);
|
|
818
|
+
const IS_BOOLEAN = (v) => typeof v === "boolean";
|
|
819
|
+
const IS_NULL = (v) => v === null;
|
|
820
|
+
const IS_ARRAY = (v) => Array.isArray(v);
|
|
821
|
+
const IS_BYTES = (v) => v instanceof Uint8Array;
|
|
822
|
+
const IS_OBJECT = (v) => isObject(v);
|
|
823
|
+
/** Whether `v` is a JSON object: not null, an array or bytes. */
|
|
824
|
+
function isObject(v) {
|
|
825
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Uint8Array);
|
|
826
|
+
}
|
|
827
|
+
/** The check of a `type` name; `bytes` (a Uint8Array) extends JSON Schema for values that never pass through JSON. */
|
|
828
|
+
const TYPE_CHECKS = /* @__PURE__ */ new Map([
|
|
829
|
+
["string", IS_STRING],
|
|
830
|
+
["number", IS_NUMBER],
|
|
831
|
+
["integer", IS_INTEGER],
|
|
832
|
+
["boolean", IS_BOOLEAN],
|
|
833
|
+
["null", IS_NULL],
|
|
834
|
+
["array", IS_ARRAY],
|
|
835
|
+
["object", IS_OBJECT],
|
|
836
|
+
["bytes", IS_BYTES]
|
|
837
|
+
]);
|
|
838
|
+
/** Leaf checks that object and array loops run inline by code instead of calling them. */
|
|
839
|
+
const LEAF_CODES = /* @__PURE__ */ new Map([
|
|
840
|
+
[IS_STRING, 1],
|
|
841
|
+
[IS_NUMBER, 2],
|
|
842
|
+
[IS_INTEGER, 3],
|
|
843
|
+
[IS_BOOLEAN, 4],
|
|
844
|
+
[IS_NULL, 5],
|
|
845
|
+
[ALWAYS, 6]
|
|
846
|
+
]);
|
|
847
|
+
function leafOk(code, x) {
|
|
848
|
+
switch (code) {
|
|
849
|
+
case 1: return typeof x === "string";
|
|
850
|
+
case 2: return typeof x === "number";
|
|
851
|
+
case 3: return Number.isInteger(x);
|
|
852
|
+
case 4: return typeof x === "boolean";
|
|
853
|
+
case 5: return x === null;
|
|
854
|
+
default: return true;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/** All of `parts`; two and three parts get closures without a loop. */
|
|
858
|
+
function and(parts) {
|
|
859
|
+
switch (parts.length) {
|
|
860
|
+
case 0: return ALWAYS;
|
|
861
|
+
case 1: return parts[0];
|
|
862
|
+
case 2: {
|
|
863
|
+
const [a, b] = parts;
|
|
864
|
+
return (v) => a(v) && b(v);
|
|
865
|
+
}
|
|
866
|
+
case 3: {
|
|
867
|
+
const [a, b, c] = parts;
|
|
868
|
+
return (v) => a(v) && b(v) && c(v);
|
|
869
|
+
}
|
|
870
|
+
default: return (v) => {
|
|
871
|
+
for (let i = 0; i < parts.length; i++) if (!parts[i](v)) return false;
|
|
872
|
+
return true;
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
/** A check whose implementation is set later: the indirection a recursive reference goes through. */
|
|
877
|
+
function indirect(slot) {
|
|
878
|
+
return (v) => slot.check(v);
|
|
879
|
+
}
|
|
880
|
+
/** `check` with `uri` pushed onto the dynamic scope while it runs (only for schemas with `$dynamicRef`). */
|
|
881
|
+
function scopedCheck(scope, uri, check) {
|
|
882
|
+
return (v) => {
|
|
883
|
+
scope.push(uri);
|
|
884
|
+
const ok = check(v);
|
|
885
|
+
scope.pop();
|
|
886
|
+
return ok;
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
/** Any of the named types. */
|
|
890
|
+
function typeCheck(types) {
|
|
891
|
+
const checks = types.map((t) => (typeof t === "string" ? TYPE_CHECKS.get(t) : void 0) ?? NEVER);
|
|
892
|
+
if (checks.length === 1) return checks[0];
|
|
893
|
+
return (v) => {
|
|
894
|
+
for (let i = 0; i < checks.length; i++) if (checks[i](v)) return true;
|
|
895
|
+
return false;
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
/** A Uint8Array within the length bounds. */
|
|
899
|
+
function bytesCheck(min, max) {
|
|
900
|
+
return (v) => v instanceof Uint8Array && v.length >= min && v.length <= max;
|
|
901
|
+
}
|
|
902
|
+
/** The number of Unicode code points of `s`: JSON Schema string lengths count code points, not UTF-16 units. */
|
|
903
|
+
function codePoints(s) {
|
|
904
|
+
let n = 0;
|
|
905
|
+
for (let i = 0; i < s.length; i++, n++) {
|
|
906
|
+
const c = s.charCodeAt(i);
|
|
907
|
+
if (c >= 55296 && c <= 56319 && i + 1 < s.length) {
|
|
908
|
+
const next = s.charCodeAt(i + 1);
|
|
909
|
+
if (next >= 56320 && next <= 57343) i++;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
return n;
|
|
913
|
+
}
|
|
914
|
+
function lengthOk(s, min, max) {
|
|
915
|
+
const units = s.length;
|
|
916
|
+
if (units < min) return false;
|
|
917
|
+
if (units < 2 * min && codePoints(s) < min) return false;
|
|
918
|
+
return units <= max || codePoints(s) <= max;
|
|
919
|
+
}
|
|
920
|
+
/** The string keywords: length bounds, pattern and format. */
|
|
921
|
+
function stringCheck(strict, min, max, re, format) {
|
|
922
|
+
if (re !== void 0 && min === 0 && max === Number.POSITIVE_INFINITY && format === void 0) return strict ? (v) => typeof v === "string" && re.test(v) : (v) => typeof v !== "string" || re.test(v);
|
|
923
|
+
if (re === void 0 && format === void 0) return strict ? (v) => typeof v === "string" && lengthOk(v, min, max) : (v) => typeof v !== "string" || lengthOk(v, min, max);
|
|
924
|
+
return (v) => {
|
|
925
|
+
if (typeof v !== "string") return !strict;
|
|
926
|
+
return lengthOk(v, min, max) && (re === void 0 || re.test(v)) && (format === void 0 || format(v));
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
/** The number keywords. `mode`: 0 passes other types, 1 requires a number, 2 an integer. */
|
|
930
|
+
function numberCheck(mode, min, max, xmin, xmax, multipleOf) {
|
|
931
|
+
return (v) => {
|
|
932
|
+
if (typeof v !== "number") return mode === 0;
|
|
933
|
+
if (mode === 2 && !Number.isInteger(v)) return false;
|
|
934
|
+
return v >= min && v <= max && v > xmin && v < xmax && (multipleOf === void 0 || isMultiple(v, multipleOf));
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
/** Whether `v` is a multiple of `d`, exactly for decimals: 0.0075 / 0.0001 is 74.99999999999999 in floating point. */
|
|
938
|
+
function isMultiple(v, d) {
|
|
939
|
+
const q = v / d;
|
|
940
|
+
if (Number.isInteger(q)) return true;
|
|
941
|
+
if (!Number.isFinite(q)) return v % d === 0;
|
|
942
|
+
const [vc, ve] = decimal(v);
|
|
943
|
+
const [dc, de] = decimal(d);
|
|
944
|
+
return ve >= de ? vc * 10n ** BigInt(ve - de) % dc === 0n : vc % (dc * 10n ** BigInt(de - ve)) === 0n;
|
|
945
|
+
}
|
|
946
|
+
function decimal(x) {
|
|
947
|
+
const [mantissa, exponent = "0"] = Math.abs(x).toString().split("e");
|
|
948
|
+
const point = mantissa.indexOf(".");
|
|
949
|
+
const fraction = point < 0 ? 0 : mantissa.length - point - 1;
|
|
950
|
+
return [BigInt(mantissa.replace(".", "")), Number(exponent) - fraction];
|
|
951
|
+
}
|
|
952
|
+
/** `inner` for objects; other values pass unless `strict`. */
|
|
953
|
+
function guardObject(inner, strict) {
|
|
954
|
+
return strict ? (v) => isObject(v) && inner(v) : (v) => !isObject(v) || inner(v);
|
|
955
|
+
}
|
|
956
|
+
/** `inner` for arrays; other values pass unless `strict`. */
|
|
957
|
+
function guardArray(inner, strict) {
|
|
958
|
+
return strict ? (v) => Array.isArray(v) && inner(v) : (v) => !Array.isArray(v) || inner(v);
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* An object with declared properties: `entries` is `[key, check, flags]` per property. The value's own keys are
|
|
962
|
+
* walked with for...in (whose `o[k]` V8 reads from the enum cache, unlike a load by a name from a list), each found
|
|
963
|
+
* among the declared names; `closed` rejects any other key. A property whose value is `undefined` counts as absent.
|
|
964
|
+
*/
|
|
965
|
+
function declaredObject(entries, requiredCount, closed, guard) {
|
|
966
|
+
const n = entries.length;
|
|
967
|
+
return (v) => {
|
|
968
|
+
if (guard !== 0 && !isObject(v)) return guard === 2;
|
|
969
|
+
const o = v;
|
|
970
|
+
let required = 0;
|
|
971
|
+
for (const k in o) {
|
|
972
|
+
let i = 0;
|
|
973
|
+
while (i < n && entries[i] !== k) i += 3;
|
|
974
|
+
if (i === n) {
|
|
975
|
+
if (closed) return false;
|
|
976
|
+
continue;
|
|
977
|
+
}
|
|
978
|
+
const x = o[k];
|
|
979
|
+
if (x === void 0) continue;
|
|
980
|
+
const f = entries[i + 2];
|
|
981
|
+
const c = f & 7;
|
|
982
|
+
if (c !== 0 ? !leafOk(c, x) : !entries[i + 1](x)) return false;
|
|
983
|
+
if (f & 8) required++;
|
|
984
|
+
}
|
|
985
|
+
return required === requiredCount;
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
/** An object with declared properties, required keys not declared, pattern properties and additional properties. */
|
|
989
|
+
function openObject(entries, keys, extraRequired, patterns, additional, guard) {
|
|
990
|
+
const known = patterns.length > 0 || additional !== void 0 ? new Set(keys) : void 0;
|
|
991
|
+
return (v) => {
|
|
992
|
+
if (guard !== 0 && !isObject(v)) return guard === 2;
|
|
993
|
+
const o = v;
|
|
994
|
+
for (let i = 0; i < entries.length; i += 3) {
|
|
995
|
+
const k = entries[i];
|
|
996
|
+
const x = o[k];
|
|
997
|
+
const f = entries[i + 2];
|
|
998
|
+
if (x === void 0 || f & 16 && !Object.hasOwn(o, k)) {
|
|
999
|
+
if (f & 8) return false;
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
const c = f & 7;
|
|
1003
|
+
if (c !== 0 ? !leafOk(c, x) : !entries[i + 1](x)) return false;
|
|
1004
|
+
}
|
|
1005
|
+
for (let i = 0; i < extraRequired.length; i++) if (!Object.hasOwn(o, extraRequired[i])) return false;
|
|
1006
|
+
if (known === void 0) return true;
|
|
1007
|
+
for (const k of Object.keys(o)) {
|
|
1008
|
+
let matched = known.has(k);
|
|
1009
|
+
for (let i = 0; i < patterns.length; i++) if (patterns[i][0].test(k)) {
|
|
1010
|
+
matched = true;
|
|
1011
|
+
if (!patterns[i][1](o[k])) return false;
|
|
1012
|
+
}
|
|
1013
|
+
if (!matched && additional !== void 0 && !additional(o[k])) return false;
|
|
1014
|
+
}
|
|
1015
|
+
return true;
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
/** Every property name passes `check` (`v` is an object). */
|
|
1019
|
+
function propertyNamesCheck(check) {
|
|
1020
|
+
return (v) => {
|
|
1021
|
+
for (const k in v) if (!check(k)) return false;
|
|
1022
|
+
return true;
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
/** `minProperties` and `maxProperties` (`v` is an object). */
|
|
1026
|
+
function propertyCountCheck(min, max) {
|
|
1027
|
+
return (v) => {
|
|
1028
|
+
let n = 0;
|
|
1029
|
+
for (const _ in v) n++;
|
|
1030
|
+
return n >= min && n <= max;
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
/** `dependentRequired` (`v` is an object). */
|
|
1034
|
+
function dependentRequiredCheck(entries) {
|
|
1035
|
+
return (v) => {
|
|
1036
|
+
const o = v;
|
|
1037
|
+
for (const [k, list] of entries) if (Object.hasOwn(o, k)) {
|
|
1038
|
+
for (const r of list) if (!Object.hasOwn(o, r)) return false;
|
|
1039
|
+
}
|
|
1040
|
+
return true;
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
/** `dependentSchemas` (`v` is an object). */
|
|
1044
|
+
function dependentSchemasCheck(entries) {
|
|
1045
|
+
return (v) => {
|
|
1046
|
+
for (const [k, check] of entries) if (Object.hasOwn(v, k) && !check(v)) return false;
|
|
1047
|
+
return true;
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
/** The common array: guard, length bounds, prefix items and the items after them, in one closure. */
|
|
1051
|
+
function listCheck(guard, min, max, prefix, rest) {
|
|
1052
|
+
const n = prefix.length;
|
|
1053
|
+
const code = rest === void 0 ? 0 : LEAF_CODES.get(rest) ?? 0;
|
|
1054
|
+
return (v) => {
|
|
1055
|
+
if (!Array.isArray(v)) return guard === 2;
|
|
1056
|
+
const length = v.length;
|
|
1057
|
+
if (length < min || length > max) return false;
|
|
1058
|
+
const m = length < n ? length : n;
|
|
1059
|
+
for (let i = 0; i < m; i++) if (!prefix[i](v[i])) return false;
|
|
1060
|
+
if (rest === void 0) return true;
|
|
1061
|
+
if (code !== 0) {
|
|
1062
|
+
for (let i = n; i < length; i++) if (!leafOk(code, v[i])) return false;
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1065
|
+
for (let i = n; i < length; i++) if (!rest(v[i])) return false;
|
|
1066
|
+
return true;
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
/** Prefix items and the items after them (`v` is an array). */
|
|
1070
|
+
function itemsCheck(prefix, rest) {
|
|
1071
|
+
return listCheck(0, 0, Number.POSITIVE_INFINITY, prefix, rest);
|
|
1072
|
+
}
|
|
1073
|
+
/** `minItems` and `maxItems` (`v` is an array). */
|
|
1074
|
+
function lengthCheck(min, max) {
|
|
1075
|
+
return (v) => v.length >= min && v.length <= max;
|
|
1076
|
+
}
|
|
1077
|
+
/** `contains` with its bounds (`v` is an array). */
|
|
1078
|
+
function containsCheck(check, min, max) {
|
|
1079
|
+
return (v) => {
|
|
1080
|
+
const list = v;
|
|
1081
|
+
let n = 0;
|
|
1082
|
+
for (let i = 0; i < list.length; i++) if (check(list[i]) && ++n > max) return false;
|
|
1083
|
+
return n >= min;
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
/** `uniqueItems` (`v` is an array). */
|
|
1087
|
+
function uniqueCheck(v) {
|
|
1088
|
+
const list = v;
|
|
1089
|
+
for (let i = 1; i < list.length; i++) for (let j = 0; j < i; j++) if (deepEqual$1(list[i], list[j])) return false;
|
|
1090
|
+
return true;
|
|
1091
|
+
}
|
|
1092
|
+
/** `enum`: up to 8 primitives by a scan, more by a Set, objects and arrays by deep equality. */
|
|
1093
|
+
function enumCheck(values) {
|
|
1094
|
+
const primitives = values.filter((x) => typeof x !== "object" || x === null);
|
|
1095
|
+
if (primitives.length === values.length && primitives.length <= 8) return (v) => {
|
|
1096
|
+
for (let i = 0; i < primitives.length; i++) if (primitives[i] === v) return true;
|
|
1097
|
+
return false;
|
|
1098
|
+
};
|
|
1099
|
+
const set = new Set(primitives);
|
|
1100
|
+
const objects = values.filter((x) => typeof x === "object" && x !== null);
|
|
1101
|
+
return (v) => set.has(v) || typeof v === "object" && objects.some((o) => deepEqual$1(v, o));
|
|
1102
|
+
}
|
|
1103
|
+
/** `const`. */
|
|
1104
|
+
function constCheck(value) {
|
|
1105
|
+
if (typeof value !== "object" || value === null) return (v) => v === value;
|
|
1106
|
+
return (v) => deepEqual$1(v, value);
|
|
1107
|
+
}
|
|
1108
|
+
/** `anyOf`. */
|
|
1109
|
+
function anyCheck(checks) {
|
|
1110
|
+
return (v) => {
|
|
1111
|
+
for (let i = 0; i < checks.length; i++) if (checks[i](v)) return true;
|
|
1112
|
+
return false;
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
/** `oneOf`. */
|
|
1116
|
+
function oneCheck(checks) {
|
|
1117
|
+
return (v) => {
|
|
1118
|
+
let n = 0;
|
|
1119
|
+
for (let i = 0; i < checks.length; i++) if (checks[i](v) && ++n > 1) return false;
|
|
1120
|
+
return n === 1;
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
/** `not`. */
|
|
1124
|
+
function notCheck(check) {
|
|
1125
|
+
return (v) => !check(v);
|
|
1126
|
+
}
|
|
1127
|
+
/** `if`, `then` and `else`. */
|
|
1128
|
+
function ifCheck(cond, then, otherwise) {
|
|
1129
|
+
return (v) => cond(v) ? then(v) : otherwise(v);
|
|
1130
|
+
}
|
|
1131
|
+
/** A union of objects tagged by a const on `key`: the tag selects the one branch that can match. */
|
|
1132
|
+
function taggedCheck(key, tags, checks) {
|
|
1133
|
+
return (v) => {
|
|
1134
|
+
if (!isObject(v)) return false;
|
|
1135
|
+
const tag = v[key];
|
|
1136
|
+
for (let i = 0; i < tags.length; i++) if (tags[i] === tag) return checks[i](v);
|
|
1137
|
+
return false;
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
/** JSON equality: same primitives, arrays with equal items in order, objects with the same keys and equal values. */
|
|
1141
|
+
function deepEqual$1(a, b) {
|
|
1142
|
+
if (a === b) return true;
|
|
1143
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
1144
|
+
const array = Array.isArray(a);
|
|
1145
|
+
if (array !== Array.isArray(b)) return false;
|
|
1146
|
+
if (array) {
|
|
1147
|
+
const x = a;
|
|
1148
|
+
const y = b;
|
|
1149
|
+
if (x.length !== y.length) return false;
|
|
1150
|
+
for (let i = 0; i < x.length; i++) if (!deepEqual$1(x[i], y[i])) return false;
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
const x = a;
|
|
1154
|
+
const y = b;
|
|
1155
|
+
const keys = Object.keys(x);
|
|
1156
|
+
if (keys.length !== Object.keys(y).length) return false;
|
|
1157
|
+
for (const k of keys) if (!Object.hasOwn(y, k) || !deepEqual$1(x[k], y[k])) return false;
|
|
1158
|
+
return true;
|
|
1159
|
+
}
|
|
1160
|
+
//#endregion
|
|
1161
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/annotations.js
|
|
1162
|
+
/** Empty annotations. */
|
|
1163
|
+
function newAnnotations() {
|
|
1164
|
+
return {
|
|
1165
|
+
props: null,
|
|
1166
|
+
allProps: false,
|
|
1167
|
+
items: 0,
|
|
1168
|
+
allItems: false,
|
|
1169
|
+
indexes: null
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
function merge(a, b) {
|
|
1173
|
+
if (b.props !== null) for (const k of b.props) addProp(a, k);
|
|
1174
|
+
a.allProps ||= b.allProps;
|
|
1175
|
+
if (b.items > a.items) a.items = b.items;
|
|
1176
|
+
a.allItems ||= b.allItems;
|
|
1177
|
+
if (b.indexes !== null) for (const i of b.indexes) addIndex(a, i);
|
|
1178
|
+
}
|
|
1179
|
+
function addProp(a, key) {
|
|
1180
|
+
if (a.props === null) a.props = /* @__PURE__ */ new Set();
|
|
1181
|
+
a.props.add(key);
|
|
1182
|
+
}
|
|
1183
|
+
function addIndex(a, index) {
|
|
1184
|
+
if (a.indexes === null) a.indexes = /* @__PURE__ */ new Set();
|
|
1185
|
+
a.indexes.add(index);
|
|
1186
|
+
}
|
|
1187
|
+
const ANNOTATING_TRUE = () => true;
|
|
1188
|
+
const ANNOTATING_FALSE = () => false;
|
|
1189
|
+
/** The indirection a recursive reference goes through. */
|
|
1190
|
+
function indirectAnnotating(slot) {
|
|
1191
|
+
return (v, a) => slot.check(v, a);
|
|
1192
|
+
}
|
|
1193
|
+
/** A plain check in annotating position: it evaluates nothing that unevaluated* sees. */
|
|
1194
|
+
function ignoreAnnotations(check) {
|
|
1195
|
+
return (v) => check(v);
|
|
1196
|
+
}
|
|
1197
|
+
/** An annotating check run as a plain check, with fresh annotations. */
|
|
1198
|
+
function withFreshAnnotations(check) {
|
|
1199
|
+
return (v) => check(v, newAnnotations());
|
|
1200
|
+
}
|
|
1201
|
+
/** `check` with `uri` pushed onto the dynamic scope while it runs. */
|
|
1202
|
+
function scopedAnnotating(scope, uri, check) {
|
|
1203
|
+
return (v, a) => {
|
|
1204
|
+
scope.push(uri);
|
|
1205
|
+
const ok = check(v, a);
|
|
1206
|
+
scope.pop();
|
|
1207
|
+
return ok;
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
/** unevaluated* sees only the annotations of its own schema, never those of its siblings in the parent. */
|
|
1211
|
+
function isolateAnnotations(check) {
|
|
1212
|
+
return (v, a) => {
|
|
1213
|
+
const b = newAnnotations();
|
|
1214
|
+
if (!check(v, b)) return false;
|
|
1215
|
+
merge(a, b);
|
|
1216
|
+
return true;
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
/** The non-annotating keywords, then each annotating part in order. */
|
|
1220
|
+
function annotateAll(plain, parts) {
|
|
1221
|
+
return (v, a) => {
|
|
1222
|
+
if (!plain(v)) return false;
|
|
1223
|
+
for (let i = 0; i < parts.length; i++) if (!parts[i](v, a)) return false;
|
|
1224
|
+
return true;
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
/** `properties`, `patternProperties` and `additionalProperties`. */
|
|
1228
|
+
function annotateObject(props, patterns, additional) {
|
|
1229
|
+
const declared = new Set(props.map(([k]) => k));
|
|
1230
|
+
return (v, a) => {
|
|
1231
|
+
if (!isObject(v)) return true;
|
|
1232
|
+
const seen = [];
|
|
1233
|
+
for (const [k, check] of props) {
|
|
1234
|
+
if (!Object.hasOwn(v, k)) continue;
|
|
1235
|
+
if (!check(v[k])) return false;
|
|
1236
|
+
seen.push(k);
|
|
1237
|
+
}
|
|
1238
|
+
for (const k of Object.keys(v)) {
|
|
1239
|
+
let matched = declared.has(k);
|
|
1240
|
+
for (const [re, check] of patterns) if (re.test(k)) {
|
|
1241
|
+
if (!check(v[k])) return false;
|
|
1242
|
+
matched = true;
|
|
1243
|
+
seen.push(k);
|
|
1244
|
+
}
|
|
1245
|
+
if (!matched && additional !== void 0) {
|
|
1246
|
+
if (!additional(v[k])) return false;
|
|
1247
|
+
seen.push(k);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
for (const k of seen) addProp(a, k);
|
|
1251
|
+
return true;
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
/** `prefixItems`/`items`/`additionalItems` and `contains` with its bounds. */
|
|
1255
|
+
function annotateArray(prefix, rest, contains, minContains, maxContains) {
|
|
1256
|
+
return (v, a) => {
|
|
1257
|
+
if (!Array.isArray(v)) return true;
|
|
1258
|
+
const m = Math.min(v.length, prefix.length);
|
|
1259
|
+
for (let i = 0; i < m; i++) if (!prefix[i](v[i])) return false;
|
|
1260
|
+
if (rest !== void 0) {
|
|
1261
|
+
for (let i = prefix.length; i < v.length; i++) if (!rest(v[i])) return false;
|
|
1262
|
+
a.allItems = true;
|
|
1263
|
+
}
|
|
1264
|
+
if (m > a.items) a.items = m;
|
|
1265
|
+
if (contains !== void 0) {
|
|
1266
|
+
let n = 0;
|
|
1267
|
+
for (let i = 0; i < v.length; i++) if (contains(v[i])) {
|
|
1268
|
+
n++;
|
|
1269
|
+
addIndex(a, i);
|
|
1270
|
+
}
|
|
1271
|
+
if (n < minContains || n > maxContains) return false;
|
|
1272
|
+
}
|
|
1273
|
+
return true;
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
/** `anyOf` (or `oneOf` when `exactlyOne`): every passing branch contributes its annotations. */
|
|
1277
|
+
function annotateAny(branches, exactlyOne) {
|
|
1278
|
+
return (v, a) => {
|
|
1279
|
+
let n = 0;
|
|
1280
|
+
for (const branch of branches) {
|
|
1281
|
+
const b = newAnnotations();
|
|
1282
|
+
if (branch(v, b)) {
|
|
1283
|
+
n++;
|
|
1284
|
+
merge(a, b);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
return exactlyOne ? n === 1 : n > 0;
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
/** `if`, `then` and `else`: a passing `if` contributes its annotations even without `then`. */
|
|
1291
|
+
function annotateIf(cond, then, otherwise) {
|
|
1292
|
+
return (v, a) => {
|
|
1293
|
+
const b = newAnnotations();
|
|
1294
|
+
if (cond(v, b)) {
|
|
1295
|
+
merge(a, b);
|
|
1296
|
+
return then === void 0 || then(v, a);
|
|
1297
|
+
}
|
|
1298
|
+
return otherwise === void 0 || otherwise(v, a);
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
/** One `dependentSchemas` entry. */
|
|
1302
|
+
function annotateDependent(key, check) {
|
|
1303
|
+
return (v, a) => !isObject(v) || !Object.hasOwn(v, key) || check(v, a);
|
|
1304
|
+
}
|
|
1305
|
+
/** `unevaluatedProperties`: every property no other keyword evaluated passes `check`. */
|
|
1306
|
+
function unevaluatedProperties(check) {
|
|
1307
|
+
return (v, a) => {
|
|
1308
|
+
if (!isObject(v) || a.allProps) return true;
|
|
1309
|
+
for (const k of Object.keys(v)) if (!(a.props?.has(k) ?? false) && !check(v[k])) return false;
|
|
1310
|
+
a.allProps = true;
|
|
1311
|
+
return true;
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
/** `unevaluatedItems`: every item no other keyword evaluated passes `check`. */
|
|
1315
|
+
function unevaluatedItems(check) {
|
|
1316
|
+
return (v, a) => {
|
|
1317
|
+
if (!Array.isArray(v) || a.allItems) return true;
|
|
1318
|
+
for (let i = a.items; i < v.length; i++) if (!(a.indexes?.has(i) ?? false) && !check(v[i])) return false;
|
|
1319
|
+
a.allItems = true;
|
|
1320
|
+
return true;
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
//#endregion
|
|
1324
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/compiler.js
|
|
1325
|
+
/** Thrown when a compile without dynamic scope tracking meets a bookended `$dynamicRef`: compile again with it. */
|
|
1326
|
+
const RESTART = Symbol("restart");
|
|
1327
|
+
/** One compile of a schema. Its caches and indexes are garbage once the root check is built. */
|
|
1328
|
+
var Compiler = class {
|
|
1329
|
+
r;
|
|
1330
|
+
draft;
|
|
1331
|
+
formats;
|
|
1332
|
+
/** Whether checks track the dynamic scope (the schema has a bookended `$dynamicRef`). */
|
|
1333
|
+
dynamic;
|
|
1334
|
+
schema;
|
|
1335
|
+
scope;
|
|
1336
|
+
cache = /* @__PURE__ */ new Map();
|
|
1337
|
+
annotatingCache = /* @__PURE__ */ new Map();
|
|
1338
|
+
constructor(schema, options, dynamic) {
|
|
1339
|
+
this.schema = schema;
|
|
1340
|
+
this.r = new Resolver(schema, options);
|
|
1341
|
+
this.draft = this.r.draft;
|
|
1342
|
+
this.formats = options.formats;
|
|
1343
|
+
this.dynamic = dynamic;
|
|
1344
|
+
this.scope = [];
|
|
1345
|
+
}
|
|
1346
|
+
/** The check of the root schema. */
|
|
1347
|
+
root() {
|
|
1348
|
+
return this.check(this.schema, this.r.rootBase);
|
|
1349
|
+
}
|
|
1350
|
+
/** The check of a schema (cached by schema object; a recursive reference goes through an indirection). */
|
|
1351
|
+
check(node, base) {
|
|
1352
|
+
if (node === true) return ALWAYS;
|
|
1353
|
+
if (node === false) return NEVER;
|
|
1354
|
+
if (!isSchemaObject$1(node)) throw new Error(`A schema must be an object or a boolean, got ${JSON.stringify(node)}`);
|
|
1355
|
+
const cached = this.cache.get(node);
|
|
1356
|
+
if (cached !== void 0) return cached;
|
|
1357
|
+
const bare = this.bareType(node);
|
|
1358
|
+
if (bare !== void 0) return bare;
|
|
1359
|
+
const slot = { check: void 0 };
|
|
1360
|
+
this.cache.set(node, indirect(slot));
|
|
1361
|
+
const check = this.build(node, this.r.baseFor(node, base));
|
|
1362
|
+
slot.check = check;
|
|
1363
|
+
this.cache.set(node, check);
|
|
1364
|
+
return check;
|
|
1365
|
+
}
|
|
1366
|
+
build(node, base) {
|
|
1367
|
+
if (this.draft === "7" && typeof node.$ref === "string") return this.ref(node.$ref, base);
|
|
1368
|
+
if (this.draft !== "7" && (node.unevaluatedProperties !== void 0 || node.unevaluatedItems !== void 0)) return withFreshAnnotations(this.annotating(node, base));
|
|
1369
|
+
const check = this.plain(node, base);
|
|
1370
|
+
return this.dynamic && this.r.isResource(node, base) ? scopedCheck(this.scope, base, check) : check;
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* The module-level check of a schema that is only a `type` (with annotations), `ALWAYS` for one with no assertion
|
|
1374
|
+
* at all; undefined for every other schema. These are the most common subschemas and cost nothing to share.
|
|
1375
|
+
*/
|
|
1376
|
+
bareType(node) {
|
|
1377
|
+
let type;
|
|
1378
|
+
for (const k in node) if (k === "type") type = node.type;
|
|
1379
|
+
else if (!NEUTRAL_KEYWORDS.has(k)) return void 0;
|
|
1380
|
+
if (type === void 0) return ALWAYS;
|
|
1381
|
+
return typeof type === "string" ? TYPE_CHECKS.get(type) : void 0;
|
|
1382
|
+
}
|
|
1383
|
+
/** Every keyword of `node`, not tracking annotations. */
|
|
1384
|
+
plain(node, base) {
|
|
1385
|
+
const parts = [];
|
|
1386
|
+
const types = node.type === void 0 ? void 0 : Array.isArray(node.type) ? node.type : [node.type];
|
|
1387
|
+
const single = types?.length === 1 ? types[0] : void 0;
|
|
1388
|
+
let typeInGroup = false;
|
|
1389
|
+
if (single === "bytes") {
|
|
1390
|
+
parts.push(bytesCheck(number(node.minLength) ?? 0, number(node.maxLength) ?? Number.POSITIVE_INFINITY));
|
|
1391
|
+
typeInGroup = true;
|
|
1392
|
+
} else {
|
|
1393
|
+
const string = this.stringGroup(node, single === "string");
|
|
1394
|
+
if (string !== void 0) parts.push(string);
|
|
1395
|
+
const numeric = single === "number" || single === "integer";
|
|
1396
|
+
const number = this.numberGroup(node, single === "number" ? 1 : single === "integer" ? 2 : 0);
|
|
1397
|
+
if (number !== void 0) parts.push(number);
|
|
1398
|
+
const object = this.objectGroup(node, base, single === "object");
|
|
1399
|
+
if (object !== void 0) parts.push(object);
|
|
1400
|
+
const array = this.arrayGroup(node, base, single === "array");
|
|
1401
|
+
if (array !== void 0) parts.push(array);
|
|
1402
|
+
typeInGroup = single === "string" && string !== void 0 || numeric && number !== void 0 || single === "object" && object !== void 0 || single === "array" && array !== void 0;
|
|
1403
|
+
}
|
|
1404
|
+
if (types !== void 0 && !typeInGroup) parts.unshift(typeCheck(types));
|
|
1405
|
+
this.inPlace(node, base, parts);
|
|
1406
|
+
return and(parts);
|
|
1407
|
+
}
|
|
1408
|
+
inPlace(node, base, parts) {
|
|
1409
|
+
if (Array.isArray(node.enum)) parts.push(enumCheck(node.enum));
|
|
1410
|
+
if (Object.hasOwn(node, "const")) parts.push(constCheck(node.const));
|
|
1411
|
+
if (Array.isArray(node.allOf)) parts.push(and(node.allOf.map((s) => this.check(s, base))));
|
|
1412
|
+
if (Array.isArray(node.anyOf)) parts.push(this.union(node.anyOf, base, false));
|
|
1413
|
+
if (Array.isArray(node.oneOf)) parts.push(this.union(node.oneOf, base, true));
|
|
1414
|
+
if (node.not !== void 0) parts.push(notCheck(this.check(node.not, base)));
|
|
1415
|
+
if (node.if !== void 0 && (node.then !== void 0 || node.else !== void 0)) {
|
|
1416
|
+
const then = node.then === void 0 ? ALWAYS : this.check(node.then, base);
|
|
1417
|
+
const otherwise = node.else === void 0 ? ALWAYS : this.check(node.else, base);
|
|
1418
|
+
parts.push(ifCheck(this.check(node.if, base), then, otherwise));
|
|
1419
|
+
}
|
|
1420
|
+
if (typeof node.$ref === "string") parts.push(this.ref(node.$ref, base));
|
|
1421
|
+
if (this.draft !== "7" && typeof node.$dynamicRef === "string") parts.push(this.dynamicRef(node.$dynamicRef, base));
|
|
1422
|
+
}
|
|
1423
|
+
union(branches, base, exactlyOne) {
|
|
1424
|
+
const checks = () => branches.map((s) => this.check(s, base));
|
|
1425
|
+
return constUnion(branches, exactlyOne) ?? this.tagged(branches, base) ?? (exactlyOne ? oneCheck(checks()) : anyCheck(checks()));
|
|
1426
|
+
}
|
|
1427
|
+
ref(ref, base) {
|
|
1428
|
+
const target = this.r.resolve(ref, base);
|
|
1429
|
+
const check = this.check(target.node, target.base);
|
|
1430
|
+
return this.dynamic && target.base !== base ? scopedCheck(this.scope, target.base, check) : check;
|
|
1431
|
+
}
|
|
1432
|
+
dynamicRef(ref, base) {
|
|
1433
|
+
const resolved = this.bookended(ref, base);
|
|
1434
|
+
if (resolved === void 0) return this.ref(ref, base);
|
|
1435
|
+
const { initial, name } = resolved;
|
|
1436
|
+
const fallback = this.check(initial.node, initial.base);
|
|
1437
|
+
const lookup = this.dynamicLookup(name, (node, b) => this.check(node, b));
|
|
1438
|
+
const scope = this.scope;
|
|
1439
|
+
return (v) => {
|
|
1440
|
+
for (let i = 0; i < scope.length; i++) {
|
|
1441
|
+
const check = lookup(scope[i]);
|
|
1442
|
+
if (check !== null) return check(v);
|
|
1443
|
+
}
|
|
1444
|
+
return fallback(v);
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
/** The initial target and anchor name of a `$dynamicRef` that resolves dynamically, or undefined for a plain ref. */
|
|
1448
|
+
bookended(ref, base) {
|
|
1449
|
+
const initial = this.r.resolve(ref, base);
|
|
1450
|
+
const uri = resolveUri(ref, base);
|
|
1451
|
+
const name = uri.slice(documentOf(uri).length + 1);
|
|
1452
|
+
const anchored = isSchemaObject$1(initial.node) && initial.node.$dynamicAnchor === name;
|
|
1453
|
+
if (name === "" || name.startsWith("/") || !anchored) return void 0;
|
|
1454
|
+
if (!this.dynamic) throw RESTART;
|
|
1455
|
+
return {
|
|
1456
|
+
initial,
|
|
1457
|
+
name
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
dynamicLookup(name, compile) {
|
|
1461
|
+
const found = /* @__PURE__ */ new Map();
|
|
1462
|
+
return (uri) => {
|
|
1463
|
+
const key = `${uri}#${name}`;
|
|
1464
|
+
let check = found.get(key);
|
|
1465
|
+
if (check === void 0) {
|
|
1466
|
+
const target = this.r.dynamicAnchors.get(key);
|
|
1467
|
+
check = target === void 0 ? null : compile(target, this.r.baseOf.get(target) ?? uri);
|
|
1468
|
+
found.set(key, check);
|
|
1469
|
+
}
|
|
1470
|
+
return check;
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
/** anyOf/oneOf whose branches are all objects with a distinct required const on one key: the tag picks the branch. */
|
|
1474
|
+
tagged(branches, base) {
|
|
1475
|
+
if (branches.length < 2) return void 0;
|
|
1476
|
+
const resolved = [];
|
|
1477
|
+
for (const branch of branches) {
|
|
1478
|
+
if (!isSchemaObject$1(branch)) return void 0;
|
|
1479
|
+
const ref = typeof branch.$ref === "string" && Object.keys(branch).length === 1 ? branch.$ref : void 0;
|
|
1480
|
+
const node = ref === void 0 ? branch : this.r.resolve(ref, this.r.baseFor(branch, base)).node;
|
|
1481
|
+
if (!isSchemaObject$1(node)) return void 0;
|
|
1482
|
+
resolved.push(node);
|
|
1483
|
+
}
|
|
1484
|
+
const first = resolved[0].properties;
|
|
1485
|
+
if (!isSchemaObject$1(first)) return void 0;
|
|
1486
|
+
for (const key of Object.keys(first)) {
|
|
1487
|
+
const tags = resolved.map((s) => tagOf(s, key));
|
|
1488
|
+
if (tags.some((t) => t === void 0) || new Set(tags).size !== tags.length) continue;
|
|
1489
|
+
return taggedCheck(key, tags, branches.map((s) => this.check(s, base)));
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
stringGroup(node, strict) {
|
|
1493
|
+
const min = number(node.minLength) ?? 0;
|
|
1494
|
+
const max = number(node.maxLength) ?? Number.POSITIVE_INFINITY;
|
|
1495
|
+
const re = typeof node.pattern === "string" ? sharedRegex(node.pattern) : void 0;
|
|
1496
|
+
const format = this.formats !== void 0 && typeof node.format === "string" && Object.hasOwn(this.formats, node.format) ? this.formats[node.format] : void 0;
|
|
1497
|
+
if (min === 0 && max === Number.POSITIVE_INFINITY && re === void 0 && format === void 0) return void 0;
|
|
1498
|
+
return stringCheck(strict, min, max, re, format);
|
|
1499
|
+
}
|
|
1500
|
+
numberGroup(node, mode) {
|
|
1501
|
+
const min = number(node.minimum);
|
|
1502
|
+
const max = number(node.maximum);
|
|
1503
|
+
const xmin = number(node.exclusiveMinimum);
|
|
1504
|
+
const xmax = number(node.exclusiveMaximum);
|
|
1505
|
+
const multipleOf = number(node.multipleOf);
|
|
1506
|
+
if ([
|
|
1507
|
+
min,
|
|
1508
|
+
max,
|
|
1509
|
+
xmin,
|
|
1510
|
+
xmax,
|
|
1511
|
+
multipleOf
|
|
1512
|
+
].every((x) => x === void 0)) return void 0;
|
|
1513
|
+
const inf = Number.POSITIVE_INFINITY;
|
|
1514
|
+
return numberCheck(mode, min ?? -inf, max ?? inf, xmin ?? -inf, xmax ?? inf, multipleOf);
|
|
1515
|
+
}
|
|
1516
|
+
objectGroup(node, base, strict) {
|
|
1517
|
+
const onlyCore = OBJECT_EXTRAS.every((k) => node[k] === void 0);
|
|
1518
|
+
const core = this.objectCore(node, base, onlyCore ? strict ? 1 : 2 : 0);
|
|
1519
|
+
if (core !== void 0 && onlyCore) return core;
|
|
1520
|
+
const parts = core === void 0 ? [] : [core];
|
|
1521
|
+
if (node.propertyNames !== void 0) parts.push(propertyNamesCheck(this.check(node.propertyNames, base)));
|
|
1522
|
+
const minProperties = number(node.minProperties);
|
|
1523
|
+
const maxProperties = number(node.maxProperties);
|
|
1524
|
+
if (minProperties !== void 0 || maxProperties !== void 0) parts.push(propertyCountCheck(minProperties ?? 0, maxProperties ?? Number.POSITIVE_INFINITY));
|
|
1525
|
+
const dependentRequired = [];
|
|
1526
|
+
const dependentSchemas = [];
|
|
1527
|
+
if (this.draft !== "7") {
|
|
1528
|
+
for (const [k, list] of entries(node.dependentRequired)) if (Array.isArray(list)) dependentRequired.push([k, list]);
|
|
1529
|
+
for (const [k, s] of entries(node.dependentSchemas)) dependentSchemas.push([k, this.check(s, base)]);
|
|
1530
|
+
}
|
|
1531
|
+
for (const [k, d] of entries(node.dependencies)) if (Array.isArray(d)) dependentRequired.push([k, d]);
|
|
1532
|
+
else dependentSchemas.push([k, this.check(d, base)]);
|
|
1533
|
+
if (dependentRequired.length > 0) parts.push(dependentRequiredCheck(dependentRequired));
|
|
1534
|
+
if (dependentSchemas.length > 0) parts.push(dependentSchemasCheck(dependentSchemas));
|
|
1535
|
+
if (parts.length === 0) return strict ? IS_OBJECT : void 0;
|
|
1536
|
+
return guardObject(and(parts), strict);
|
|
1537
|
+
}
|
|
1538
|
+
objectCore(node, base, guard) {
|
|
1539
|
+
const properties = isSchemaObject$1(node.properties) ? node.properties : {};
|
|
1540
|
+
const required = Array.isArray(node.required) ? node.required.filter((k) => typeof k === "string") : [];
|
|
1541
|
+
const patterns = isSchemaObject$1(node.patternProperties) ? node.patternProperties : {};
|
|
1542
|
+
const additional = node.additionalProperties;
|
|
1543
|
+
const keys = Object.keys(properties);
|
|
1544
|
+
const patternKeys = Object.keys(patterns);
|
|
1545
|
+
if (keys.length + required.length + patternKeys.length === 0 && (additional === void 0 || additional === true)) return;
|
|
1546
|
+
const entries = [];
|
|
1547
|
+
for (const k of keys) {
|
|
1548
|
+
const check = this.check(properties[k], base);
|
|
1549
|
+
const flags = (LEAF_CODES.get(check) ?? 0) | (required.includes(k) ? 8 : 0) | (k in Object.prototype ? 16 : 0);
|
|
1550
|
+
entries.push(k, check, flags);
|
|
1551
|
+
}
|
|
1552
|
+
const extraRequired = required.filter((k) => !Object.hasOwn(properties, k));
|
|
1553
|
+
const pats = patternKeys.map((p) => [sharedRegex(p), this.check(patterns[p], base)]);
|
|
1554
|
+
const extra = additional === void 0 || additional === true ? void 0 : this.check(additional, base);
|
|
1555
|
+
if (pats.length === 0 && extraRequired.length === 0 && (extra === void 0 || additional === false)) {
|
|
1556
|
+
const requiredCount = keys.filter((k) => required.includes(k)).length;
|
|
1557
|
+
return declaredObject(entries, requiredCount, additional === false, guard);
|
|
1558
|
+
}
|
|
1559
|
+
return openObject(entries, keys, extraRequired, pats, extra, guard);
|
|
1560
|
+
}
|
|
1561
|
+
arrayGroup(node, base, strict) {
|
|
1562
|
+
let prefix = [];
|
|
1563
|
+
let rest;
|
|
1564
|
+
if (Array.isArray(node.items)) {
|
|
1565
|
+
prefix = node.items;
|
|
1566
|
+
rest = node.additionalItems;
|
|
1567
|
+
} else {
|
|
1568
|
+
if (this.draft !== "7" && Array.isArray(node.prefixItems)) prefix = node.prefixItems;
|
|
1569
|
+
rest = node.items;
|
|
1570
|
+
}
|
|
1571
|
+
const prefixChecks = prefix.map((s) => this.check(s, base));
|
|
1572
|
+
const restCheck = rest === void 0 || rest === true ? void 0 : this.check(rest, base);
|
|
1573
|
+
const minItems = number(node.minItems);
|
|
1574
|
+
const maxItems = number(node.maxItems);
|
|
1575
|
+
if (node.contains === void 0 && node.uniqueItems !== true && (prefixChecks.length > 0 || restCheck !== void 0)) return listCheck(strict ? 1 : 2, minItems ?? 0, maxItems ?? Number.POSITIVE_INFINITY, prefixChecks, restCheck);
|
|
1576
|
+
const parts = [];
|
|
1577
|
+
if (prefixChecks.length > 0 || restCheck !== void 0) parts.push(itemsCheck(prefixChecks, restCheck));
|
|
1578
|
+
if (minItems !== void 0 || maxItems !== void 0) parts.push(lengthCheck(minItems ?? 0, maxItems ?? Number.POSITIVE_INFINITY));
|
|
1579
|
+
if (node.contains !== void 0) {
|
|
1580
|
+
const min = this.draft === "7" ? 1 : number(node.minContains) ?? 1;
|
|
1581
|
+
const max = this.draft === "7" ? Number.POSITIVE_INFINITY : number(node.maxContains) ?? Number.POSITIVE_INFINITY;
|
|
1582
|
+
parts.push(containsCheck(this.check(node.contains, base), min, max));
|
|
1583
|
+
}
|
|
1584
|
+
if (node.uniqueItems === true) parts.push(uniqueCheck);
|
|
1585
|
+
if (parts.length === 0) return strict ? IS_ARRAY : void 0;
|
|
1586
|
+
return guardArray(and(parts), strict);
|
|
1587
|
+
}
|
|
1588
|
+
/** The annotating check of a schema evaluated in place (only below `unevaluatedProperties`/`unevaluatedItems`). */
|
|
1589
|
+
annotating(node, base) {
|
|
1590
|
+
if (node === true) return ANNOTATING_TRUE;
|
|
1591
|
+
if (node === false) return ANNOTATING_FALSE;
|
|
1592
|
+
if (!isSchemaObject$1(node)) throw new Error(`A schema must be an object or a boolean, got ${JSON.stringify(node)}`);
|
|
1593
|
+
const cached = this.annotatingCache.get(node);
|
|
1594
|
+
if (cached !== void 0) return cached;
|
|
1595
|
+
const slot = { check: void 0 };
|
|
1596
|
+
this.annotatingCache.set(node, indirectAnnotating(slot));
|
|
1597
|
+
const check = this.buildAnnotating(node, this.r.baseFor(node, base));
|
|
1598
|
+
slot.check = check;
|
|
1599
|
+
this.annotatingCache.set(node, check);
|
|
1600
|
+
return check;
|
|
1601
|
+
}
|
|
1602
|
+
buildAnnotating(node, base) {
|
|
1603
|
+
const rest = {};
|
|
1604
|
+
let annotates = false;
|
|
1605
|
+
for (const k of Object.keys(node)) if (ANNOTATING.has(k)) annotates = true;
|
|
1606
|
+
else rest[k] = node[k];
|
|
1607
|
+
const plain = this.plain(rest, base);
|
|
1608
|
+
const parts = [];
|
|
1609
|
+
if (annotates) this.annotatingParts(node, base, parts);
|
|
1610
|
+
const all = parts.length === 0 ? ignoreAnnotations(plain) : annotateAll(plain, parts);
|
|
1611
|
+
const own = node.unevaluatedProperties !== void 0 || node.unevaluatedItems !== void 0 ? isolateAnnotations(all) : all;
|
|
1612
|
+
return this.dynamic && this.r.isResource(node, base) ? scopedAnnotating(this.scope, base, own) : own;
|
|
1613
|
+
}
|
|
1614
|
+
annotatingParts(node, base, parts) {
|
|
1615
|
+
if (node.properties !== void 0 || node.patternProperties !== void 0 || node.additionalProperties !== void 0) {
|
|
1616
|
+
const props = entries(node.properties).map(([k, s]) => [k, this.check(s, base)]);
|
|
1617
|
+
const pats = entries(node.patternProperties).map(([p, s]) => [sharedRegex(p), this.check(s, base)]);
|
|
1618
|
+
const extra = node.additionalProperties === void 0 ? void 0 : this.check(node.additionalProperties, base);
|
|
1619
|
+
parts.push(annotateObject(props, pats, extra));
|
|
1620
|
+
}
|
|
1621
|
+
if (node.prefixItems !== void 0 || node.items !== void 0 || node.contains !== void 0) {
|
|
1622
|
+
const prefix = Array.isArray(node.prefixItems) ? node.prefixItems : Array.isArray(node.items) ? node.items : [];
|
|
1623
|
+
const rest = Array.isArray(node.items) ? node.additionalItems : node.items;
|
|
1624
|
+
parts.push(annotateArray(prefix.map((s) => this.check(s, base)), rest === void 0 ? void 0 : this.check(rest, base), node.contains === void 0 ? void 0 : this.check(node.contains, base), number(node.minContains) ?? 1, number(node.maxContains) ?? Number.POSITIVE_INFINITY));
|
|
1625
|
+
}
|
|
1626
|
+
if (Array.isArray(node.allOf)) for (const s of node.allOf) parts.push(this.annotating(s, base));
|
|
1627
|
+
if (Array.isArray(node.anyOf)) parts.push(annotateAny(node.anyOf.map((s) => this.annotating(s, base)), false));
|
|
1628
|
+
if (Array.isArray(node.oneOf)) parts.push(annotateAny(node.oneOf.map((s) => this.annotating(s, base)), true));
|
|
1629
|
+
if (node.if !== void 0) {
|
|
1630
|
+
const then = node.then === void 0 ? void 0 : this.annotating(node.then, base);
|
|
1631
|
+
const otherwise = node.else === void 0 ? void 0 : this.annotating(node.else, base);
|
|
1632
|
+
parts.push(annotateIf(this.annotating(node.if, base), then, otherwise));
|
|
1633
|
+
}
|
|
1634
|
+
if (typeof node.$ref === "string") parts.push(this.annotatingRef(node.$ref, base));
|
|
1635
|
+
if (typeof node.$dynamicRef === "string") parts.push(this.annotatingDynamicRef(node.$dynamicRef, base));
|
|
1636
|
+
for (const [k, s] of entries(node.dependentSchemas)) parts.push(annotateDependent(k, this.annotating(s, base)));
|
|
1637
|
+
if (node.unevaluatedProperties !== void 0) parts.push(unevaluatedProperties(this.check(node.unevaluatedProperties, base)));
|
|
1638
|
+
if (node.unevaluatedItems !== void 0) parts.push(unevaluatedItems(this.check(node.unevaluatedItems, base)));
|
|
1639
|
+
}
|
|
1640
|
+
annotatingRef(ref, base) {
|
|
1641
|
+
const target = this.r.resolve(ref, base);
|
|
1642
|
+
const check = this.annotating(target.node, target.base);
|
|
1643
|
+
return this.dynamic && target.base !== base ? scopedAnnotating(this.scope, target.base, check) : check;
|
|
1644
|
+
}
|
|
1645
|
+
annotatingDynamicRef(ref, base) {
|
|
1646
|
+
const resolved = this.bookended(ref, base);
|
|
1647
|
+
if (resolved === void 0) return this.annotatingRef(ref, base);
|
|
1648
|
+
const { initial, name } = resolved;
|
|
1649
|
+
const fallback = this.annotating(initial.node, initial.base);
|
|
1650
|
+
const lookup = this.dynamicLookup(name, (node, b) => this.annotating(node, b));
|
|
1651
|
+
const scope = this.scope;
|
|
1652
|
+
return (v, a) => {
|
|
1653
|
+
for (let i = 0; i < scope.length; i++) {
|
|
1654
|
+
const check = lookup(scope[i]);
|
|
1655
|
+
if (check !== null) return check(v, a);
|
|
1656
|
+
}
|
|
1657
|
+
return fallback(v, a);
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
/** Keywords that never affect a check. */
|
|
1662
|
+
const NEUTRAL_KEYWORDS = /* @__PURE__ */ new Set([
|
|
1663
|
+
"$schema",
|
|
1664
|
+
"$comment",
|
|
1665
|
+
"title",
|
|
1666
|
+
"description",
|
|
1667
|
+
"default",
|
|
1668
|
+
"examples",
|
|
1669
|
+
"deprecated",
|
|
1670
|
+
"readOnly",
|
|
1671
|
+
"writeOnly",
|
|
1672
|
+
"$defs",
|
|
1673
|
+
"definitions",
|
|
1674
|
+
"contentEncoding",
|
|
1675
|
+
"contentMediaType",
|
|
1676
|
+
"minContains",
|
|
1677
|
+
"maxContains",
|
|
1678
|
+
"$vocabulary"
|
|
1679
|
+
]);
|
|
1680
|
+
const OBJECT_EXTRAS = [
|
|
1681
|
+
"propertyNames",
|
|
1682
|
+
"minProperties",
|
|
1683
|
+
"maxProperties",
|
|
1684
|
+
"dependentRequired",
|
|
1685
|
+
"dependentSchemas",
|
|
1686
|
+
"dependencies"
|
|
1687
|
+
];
|
|
1688
|
+
const ANNOTATING = /* @__PURE__ */ new Set([
|
|
1689
|
+
"properties",
|
|
1690
|
+
"patternProperties",
|
|
1691
|
+
"additionalProperties",
|
|
1692
|
+
"prefixItems",
|
|
1693
|
+
"items",
|
|
1694
|
+
"additionalItems",
|
|
1695
|
+
"contains",
|
|
1696
|
+
"minContains",
|
|
1697
|
+
"maxContains",
|
|
1698
|
+
"allOf",
|
|
1699
|
+
"anyOf",
|
|
1700
|
+
"oneOf",
|
|
1701
|
+
"if",
|
|
1702
|
+
"then",
|
|
1703
|
+
"else",
|
|
1704
|
+
"$ref",
|
|
1705
|
+
"$dynamicRef",
|
|
1706
|
+
"dependentSchemas",
|
|
1707
|
+
"unevaluatedProperties",
|
|
1708
|
+
"unevaluatedItems"
|
|
1709
|
+
]);
|
|
1710
|
+
/** anyOf/oneOf whose branches are all `{ const: primitive }`: an enum (distinct values make oneOf the same). */
|
|
1711
|
+
function constUnion(branches, exactlyOne) {
|
|
1712
|
+
const values = [];
|
|
1713
|
+
for (const branch of branches) {
|
|
1714
|
+
if (!isSchemaObject$1(branch) || !Object.hasOwn(branch, "const")) return void 0;
|
|
1715
|
+
for (const k of Object.keys(branch)) if (k !== "const" && !NEUTRAL_KEYWORDS.has(k)) return void 0;
|
|
1716
|
+
if (typeof branch.const === "object" && branch.const !== null) return void 0;
|
|
1717
|
+
if (exactlyOne && values.includes(branch.const)) return void 0;
|
|
1718
|
+
values.push(branch.const);
|
|
1719
|
+
}
|
|
1720
|
+
return enumCheck(values);
|
|
1721
|
+
}
|
|
1722
|
+
function tagOf(branch, key) {
|
|
1723
|
+
const properties = branch.properties;
|
|
1724
|
+
if (branch.type !== "object" || !Array.isArray(branch.required) || !branch.required.includes(key)) return void 0;
|
|
1725
|
+
const tag = isSchemaObject$1(properties) ? properties[key] : void 0;
|
|
1726
|
+
if (!isSchemaObject$1(tag) || !Object.hasOwn(tag, "const")) return void 0;
|
|
1727
|
+
return typeof tag.const === "object" && tag.const !== null ? void 0 : tag.const;
|
|
1728
|
+
}
|
|
1729
|
+
function number(value) {
|
|
1730
|
+
return typeof value === "number" ? value : void 0;
|
|
1731
|
+
}
|
|
1732
|
+
function entries(value) {
|
|
1733
|
+
return isSchemaObject$1(value) ? Object.entries(value) : [];
|
|
1734
|
+
}
|
|
1735
|
+
//#endregion
|
|
1736
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/explain.js
|
|
1737
|
+
/** Explains failures of one compiled schema. */
|
|
1738
|
+
var Explainer = class {
|
|
1739
|
+
c;
|
|
1740
|
+
schema;
|
|
1741
|
+
/**
|
|
1742
|
+
* The errors of `$ref` targets for object values, within one errors() call: a recursive union explains each branch
|
|
1743
|
+
* to pick the one to blame, and every branch would explain the same children again, exponentially in the depth.
|
|
1744
|
+
*/
|
|
1745
|
+
memo = void 0;
|
|
1746
|
+
constructor(compiler, schema) {
|
|
1747
|
+
this.c = compiler;
|
|
1748
|
+
this.schema = schema;
|
|
1749
|
+
compiler.root();
|
|
1750
|
+
}
|
|
1751
|
+
/** The errors of `value`, at least one (`value` failed the check). */
|
|
1752
|
+
errors(value) {
|
|
1753
|
+
const out = [];
|
|
1754
|
+
try {
|
|
1755
|
+
this.walk(this.schema, this.c.r.rootBase, value, "", out);
|
|
1756
|
+
} finally {
|
|
1757
|
+
this.memo = void 0;
|
|
1758
|
+
}
|
|
1759
|
+
if (out.length === 0) out.push({
|
|
1760
|
+
path: "",
|
|
1761
|
+
keyword: "schema",
|
|
1762
|
+
message: "invalid"
|
|
1763
|
+
});
|
|
1764
|
+
return out;
|
|
1765
|
+
}
|
|
1766
|
+
ok(node, base, v) {
|
|
1767
|
+
return this.c.check(node, base)(v);
|
|
1768
|
+
}
|
|
1769
|
+
walk(node, base, v, path, out) {
|
|
1770
|
+
if (node === true) return;
|
|
1771
|
+
if (node === false) {
|
|
1772
|
+
out.push({
|
|
1773
|
+
path,
|
|
1774
|
+
keyword: "false",
|
|
1775
|
+
message: "no value is allowed here"
|
|
1776
|
+
});
|
|
1777
|
+
return;
|
|
1778
|
+
}
|
|
1779
|
+
if (!isSchemaObject$1(node)) return;
|
|
1780
|
+
const b = this.c.r.baseFor(node, base);
|
|
1781
|
+
if (this.ok(node, b, v)) return;
|
|
1782
|
+
const start = out.length;
|
|
1783
|
+
const push = (keyword, message, at = path) => {
|
|
1784
|
+
out.push({
|
|
1785
|
+
path: at,
|
|
1786
|
+
keyword,
|
|
1787
|
+
message
|
|
1788
|
+
});
|
|
1789
|
+
};
|
|
1790
|
+
if (this.c.draft === "7" && typeof node.$ref === "string") {
|
|
1791
|
+
this.walkRef(node.$ref, b, v, path, out);
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
if (node.type !== void 0) {
|
|
1795
|
+
const types = Array.isArray(node.type) ? node.type : [node.type];
|
|
1796
|
+
if (!types.map((t) => (typeof t === "string" ? TYPE_CHECKS.get(t) : void 0) ?? NEVER).some((check) => check(v))) {
|
|
1797
|
+
push("type", `expected ${types.join(" or ")}, got ${typeName(v)}`);
|
|
1798
|
+
return;
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
if (Array.isArray(node.enum) && !enumCheck(node.enum)(v)) push("enum", `expected one of ${listValues(node.enum)}`);
|
|
1802
|
+
if (Object.hasOwn(node, "const") && !constCheck(node.const)(v)) push("const", `expected ${JSON.stringify(node.const)}`);
|
|
1803
|
+
if (typeof v === "string" && node.type !== "bytes") this.walkString(node, v, push);
|
|
1804
|
+
if (v instanceof Uint8Array && node.type === "bytes") this.walkBytes(node, v, push);
|
|
1805
|
+
if (typeof v === "number") this.walkNumber(node, v, push);
|
|
1806
|
+
if (isObject(v)) this.walkObject(node, b, v, path, out, push);
|
|
1807
|
+
if (Array.isArray(v)) this.walkArray(node, b, v, path, out, push);
|
|
1808
|
+
if (Array.isArray(node.allOf)) for (const s of node.allOf) this.walk(s, b, v, path, out);
|
|
1809
|
+
if (Array.isArray(node.anyOf)) this.walkUnion(node.anyOf, b, v, path, out, false);
|
|
1810
|
+
if (Array.isArray(node.oneOf)) this.walkUnion(node.oneOf, b, v, path, out, true);
|
|
1811
|
+
if (node.not !== void 0 && this.ok(node.not, b, v)) push("not", "must not match the schema in not");
|
|
1812
|
+
if (node.if !== void 0) {
|
|
1813
|
+
const branch = this.ok(node.if, b, v) ? node.then : node.else;
|
|
1814
|
+
if (branch !== void 0) this.walk(branch, b, v, path, out);
|
|
1815
|
+
}
|
|
1816
|
+
if (typeof node.$ref === "string") this.walkRef(node.$ref, b, v, path, out);
|
|
1817
|
+
if (out.length === start && (node.unevaluatedProperties !== void 0 || node.unevaluatedItems !== void 0)) this.walkUnevaluated(node, b, v, path, out);
|
|
1818
|
+
if (out.length === start && typeof node.$dynamicRef === "string") push("$dynamicRef", "does not match the dynamically referenced schema");
|
|
1819
|
+
}
|
|
1820
|
+
walkRef(ref, base, v, path, out) {
|
|
1821
|
+
const target = this.c.r.resolve(ref, base);
|
|
1822
|
+
if (target.node === false && this.c.r.isUnresolved(ref, base)) {
|
|
1823
|
+
out.push({
|
|
1824
|
+
path,
|
|
1825
|
+
keyword: "$ref",
|
|
1826
|
+
message: `unresolved reference ${ref}`
|
|
1827
|
+
});
|
|
1828
|
+
return;
|
|
1829
|
+
}
|
|
1830
|
+
if (!isSchemaObject$1(target.node) || typeof v !== "object" || v === null) {
|
|
1831
|
+
this.walk(target.node, target.base, v, path, out);
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
this.memo ??= /* @__PURE__ */ new Map();
|
|
1835
|
+
let values = this.memo.get(target.node);
|
|
1836
|
+
const known = values?.get(v);
|
|
1837
|
+
if (known !== void 0 && known.path === path) {
|
|
1838
|
+
out.push(...known.errors);
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
const errors = [];
|
|
1842
|
+
this.walk(target.node, target.base, v, path, errors);
|
|
1843
|
+
if (values === void 0) {
|
|
1844
|
+
values = /* @__PURE__ */ new Map();
|
|
1845
|
+
this.memo.set(target.node, values);
|
|
1846
|
+
}
|
|
1847
|
+
values.set(v, {
|
|
1848
|
+
path,
|
|
1849
|
+
errors
|
|
1850
|
+
});
|
|
1851
|
+
out.push(...errors);
|
|
1852
|
+
}
|
|
1853
|
+
walkString(node, v, push) {
|
|
1854
|
+
const n = codePoints(v);
|
|
1855
|
+
if (typeof node.minLength === "number" && n < node.minLength) push("minLength", `expected at least ${node.minLength} characters`);
|
|
1856
|
+
if (typeof node.maxLength === "number" && n > node.maxLength) push("maxLength", `expected at most ${node.maxLength} characters`);
|
|
1857
|
+
if (typeof node.pattern === "string" && !sharedRegex(node.pattern).test(v)) push("pattern", `expected to match ${node.pattern}`);
|
|
1858
|
+
const formats = this.c.formats;
|
|
1859
|
+
const format = formats !== void 0 && typeof node.format === "string" && Object.hasOwn(formats, node.format) ? formats[node.format] : void 0;
|
|
1860
|
+
if (format !== void 0 && !format(v)) push("format", `expected format ${node.format}`);
|
|
1861
|
+
}
|
|
1862
|
+
walkBytes(node, v, push) {
|
|
1863
|
+
if (typeof node.minLength === "number" && v.length < node.minLength) push("minLength", `expected at least ${node.minLength} bytes`);
|
|
1864
|
+
if (typeof node.maxLength === "number" && v.length > node.maxLength) push("maxLength", `expected at most ${node.maxLength} bytes`);
|
|
1865
|
+
}
|
|
1866
|
+
walkNumber(node, v, push) {
|
|
1867
|
+
if (typeof node.minimum === "number" && v < node.minimum) push("minimum", `expected >= ${node.minimum}`);
|
|
1868
|
+
if (typeof node.maximum === "number" && v > node.maximum) push("maximum", `expected <= ${node.maximum}`);
|
|
1869
|
+
if (typeof node.exclusiveMinimum === "number" && v <= node.exclusiveMinimum) push("exclusiveMinimum", `expected > ${node.exclusiveMinimum}`);
|
|
1870
|
+
if (typeof node.exclusiveMaximum === "number" && v >= node.exclusiveMaximum) push("exclusiveMaximum", `expected < ${node.exclusiveMaximum}`);
|
|
1871
|
+
if (typeof node.multipleOf === "number" && !isMultiple(v, node.multipleOf)) push("multipleOf", `expected a multiple of ${node.multipleOf}`);
|
|
1872
|
+
}
|
|
1873
|
+
walkObject(node, b, v, path, out, push) {
|
|
1874
|
+
const properties = isSchemaObject$1(node.properties) ? node.properties : {};
|
|
1875
|
+
const required = Array.isArray(node.required) ? node.required : [];
|
|
1876
|
+
for (const k of required) if (typeof k === "string" && (!Object.hasOwn(v, k) || v[k] === void 0)) push("required", "missing", pointer(path, k));
|
|
1877
|
+
for (const k of Object.keys(properties)) if (Object.hasOwn(v, k) && v[k] !== void 0) this.walk(properties[k], b, v[k], pointer(path, k), out);
|
|
1878
|
+
const patterns = isSchemaObject$1(node.patternProperties) ? Object.entries(node.patternProperties) : [];
|
|
1879
|
+
for (const k of Object.keys(v)) {
|
|
1880
|
+
let matched = Object.hasOwn(properties, k);
|
|
1881
|
+
for (const [p, s] of patterns) if (sharedRegex(p).test(k)) {
|
|
1882
|
+
matched = true;
|
|
1883
|
+
this.walk(s, b, v[k], pointer(path, k), out);
|
|
1884
|
+
}
|
|
1885
|
+
if (!matched && node.additionalProperties !== void 0) {
|
|
1886
|
+
if (node.additionalProperties === false) push("additionalProperties", "unknown field", pointer(path, k));
|
|
1887
|
+
else this.walk(node.additionalProperties, b, v[k], pointer(path, k), out);
|
|
1888
|
+
}
|
|
1889
|
+
if (node.propertyNames !== void 0 && !this.ok(node.propertyNames, b, k)) push("propertyNames", "invalid property name", pointer(path, k));
|
|
1890
|
+
}
|
|
1891
|
+
const count = Object.keys(v).length;
|
|
1892
|
+
if (typeof node.minProperties === "number" && count < node.minProperties) push("minProperties", `expected at least ${node.minProperties} properties`);
|
|
1893
|
+
if (typeof node.maxProperties === "number" && count > node.maxProperties) push("maxProperties", `expected at most ${node.maxProperties} properties`);
|
|
1894
|
+
const dependencies = {
|
|
1895
|
+
...this.c.draft === "7" || !isSchemaObject$1(node.dependentRequired) ? {} : node.dependentRequired,
|
|
1896
|
+
...isSchemaObject$1(node.dependencies) ? node.dependencies : {}
|
|
1897
|
+
};
|
|
1898
|
+
for (const [k, d] of Object.entries(dependencies)) {
|
|
1899
|
+
if (!Object.hasOwn(v, k)) continue;
|
|
1900
|
+
if (!Array.isArray(d)) this.walk(d, b, v, path, out);
|
|
1901
|
+
else for (const r of d) if (!Object.hasOwn(v, r)) push("dependentRequired", `required when ${k} is present`, pointer(path, r));
|
|
1902
|
+
}
|
|
1903
|
+
if (this.c.draft !== "7" && isSchemaObject$1(node.dependentSchemas)) {
|
|
1904
|
+
for (const [k, s] of Object.entries(node.dependentSchemas)) if (Object.hasOwn(v, k)) this.walk(s, b, v, path, out);
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
walkArray(node, b, v, path, out, push) {
|
|
1908
|
+
let prefix = [];
|
|
1909
|
+
let rest;
|
|
1910
|
+
if (Array.isArray(node.items)) {
|
|
1911
|
+
prefix = node.items;
|
|
1912
|
+
rest = node.additionalItems;
|
|
1913
|
+
} else {
|
|
1914
|
+
if (this.c.draft !== "7" && Array.isArray(node.prefixItems)) prefix = node.prefixItems;
|
|
1915
|
+
rest = node.items;
|
|
1916
|
+
}
|
|
1917
|
+
for (let i = 0; i < v.length; i++) {
|
|
1918
|
+
const s = i < prefix.length ? prefix[i] : rest;
|
|
1919
|
+
if (s !== void 0) this.walk(s, b, v[i], `${path}/${i}`, out);
|
|
1920
|
+
}
|
|
1921
|
+
if (typeof node.minItems === "number" && v.length < node.minItems) push("minItems", `expected at least ${node.minItems} items`);
|
|
1922
|
+
if (typeof node.maxItems === "number" && v.length > node.maxItems) push("maxItems", `expected at most ${node.maxItems} items`);
|
|
1923
|
+
if (node.uniqueItems === true && !uniqueCheck(v)) push("uniqueItems", "expected unique items");
|
|
1924
|
+
if (node.contains !== void 0) {
|
|
1925
|
+
const draft7 = this.c.draft === "7";
|
|
1926
|
+
const min = draft7 || typeof node.minContains !== "number" ? 1 : node.minContains;
|
|
1927
|
+
const max = draft7 || typeof node.maxContains !== "number" ? Number.POSITIVE_INFINITY : node.maxContains;
|
|
1928
|
+
if (!containsCheck(this.c.check(node.contains, b), min, max)(v)) push("contains", containsMessage(min, max));
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
walkUnion(branches, b, v, path, out, exactlyOne) {
|
|
1932
|
+
const matches = branches.filter((s) => this.ok(s, b, v)).length;
|
|
1933
|
+
if (matches === 1 || !exactlyOne && matches > 0) return;
|
|
1934
|
+
const keyword = exactlyOne ? "oneOf" : "anyOf";
|
|
1935
|
+
if (matches > 1) {
|
|
1936
|
+
out.push({
|
|
1937
|
+
path,
|
|
1938
|
+
keyword,
|
|
1939
|
+
message: "matches more than one alternative"
|
|
1940
|
+
});
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1943
|
+
const tag = this.tagOf(branches, b);
|
|
1944
|
+
if (tag !== void 0 && isObject(v)) {
|
|
1945
|
+
const i = tag.values.indexOf(v[tag.key]);
|
|
1946
|
+
if (i < 0) out.push({
|
|
1947
|
+
path: pointer(path, tag.key),
|
|
1948
|
+
keyword,
|
|
1949
|
+
message: `expected one of ${listValues(tag.values)}`
|
|
1950
|
+
});
|
|
1951
|
+
else this.walk(branches[i], b, v, path, out);
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
let best;
|
|
1955
|
+
for (const s of branches) {
|
|
1956
|
+
const errors = [];
|
|
1957
|
+
this.walk(s, b, v, path, errors);
|
|
1958
|
+
if (errors.length === 0) continue;
|
|
1959
|
+
const declared = isObject(v) ? this.declaredKeys(s, b, v) : 0;
|
|
1960
|
+
if (best === void 0 || declared > best.declared || declared === best.declared && errors[0].path.length > best.errors[0].path.length) best = {
|
|
1961
|
+
errors,
|
|
1962
|
+
declared
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
out.push(...best?.errors ?? [{
|
|
1966
|
+
path,
|
|
1967
|
+
keyword,
|
|
1968
|
+
message: "matches no alternative"
|
|
1969
|
+
}]);
|
|
1970
|
+
}
|
|
1971
|
+
/** How many of the keys of `v` the branch `s` (through a `$ref`) declares in `properties`. */
|
|
1972
|
+
declaredKeys(s, b, v) {
|
|
1973
|
+
const node = isSchemaObject$1(s) && typeof s.$ref === "string" ? this.c.r.resolve(s.$ref, b).node : s;
|
|
1974
|
+
const properties = isSchemaObject$1(node) && isSchemaObject$1(node.properties) ? node.properties : {};
|
|
1975
|
+
return Object.keys(v).filter((k) => Object.hasOwn(properties, k)).length;
|
|
1976
|
+
}
|
|
1977
|
+
tagOf(branches, b) {
|
|
1978
|
+
const resolved = branches.map((s) => isSchemaObject$1(s) && typeof s.$ref === "string" ? this.c.r.resolve(s.$ref, b).node : s);
|
|
1979
|
+
const first = resolved[0];
|
|
1980
|
+
if (!isSchemaObject$1(first) || !isSchemaObject$1(first.properties)) return void 0;
|
|
1981
|
+
for (const key of Object.keys(first.properties)) {
|
|
1982
|
+
const values = resolved.map((s) => {
|
|
1983
|
+
const tag = isSchemaObject$1(s) && isSchemaObject$1(s.properties) ? s.properties[key] : void 0;
|
|
1984
|
+
return isSchemaObject$1(tag) ? tag.const : void 0;
|
|
1985
|
+
});
|
|
1986
|
+
if (values.every((x) => x !== void 0 && (typeof x !== "object" || x === null)) && new Set(values).size === values.length) return {
|
|
1987
|
+
key,
|
|
1988
|
+
values
|
|
1989
|
+
};
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
walkUnevaluated(node, b, v, path, out) {
|
|
1993
|
+
const { unevaluatedProperties, unevaluatedItems, ...rest } = node;
|
|
1994
|
+
const a = newAnnotations();
|
|
1995
|
+
this.c.annotating(rest, b)(v, a);
|
|
1996
|
+
if (isObject(v) && unevaluatedProperties !== void 0 && !a.allProps) for (const k of Object.keys(v)) {
|
|
1997
|
+
if (a.props?.has(k)) continue;
|
|
1998
|
+
if (unevaluatedProperties === false) out.push({
|
|
1999
|
+
path: pointer(path, k),
|
|
2000
|
+
keyword: "unevaluatedProperties",
|
|
2001
|
+
message: "unknown field"
|
|
2002
|
+
});
|
|
2003
|
+
else this.walk(unevaluatedProperties, b, v[k], pointer(path, k), out);
|
|
2004
|
+
}
|
|
2005
|
+
if (Array.isArray(v) && unevaluatedItems !== void 0 && !a.allItems) for (let i = a.items; i < v.length; i++) {
|
|
2006
|
+
if (a.indexes?.has(i)) continue;
|
|
2007
|
+
if (unevaluatedItems === false) out.push({
|
|
2008
|
+
path: `${path}/${i}`,
|
|
2009
|
+
keyword: "unevaluatedItems",
|
|
2010
|
+
message: "unexpected item"
|
|
2011
|
+
});
|
|
2012
|
+
else this.walk(unevaluatedItems, b, v[i], `${path}/${i}`, out);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
2016
|
+
const LISTED_VALUES = 20;
|
|
2017
|
+
/** `values` as JSON, at most LISTED_VALUES of them, then how many more there are. */
|
|
2018
|
+
function listValues(values) {
|
|
2019
|
+
if (values.length <= LISTED_VALUES) return JSON.stringify(values);
|
|
2020
|
+
return `${JSON.stringify(values.slice(0, LISTED_VALUES)).slice(0, -1)}, ... and ${values.length - LISTED_VALUES} more]`;
|
|
2021
|
+
}
|
|
2022
|
+
function containsMessage(min, max) {
|
|
2023
|
+
if (max === Number.POSITIVE_INFINITY) return `expected at least ${min} matching ${min === 1 ? "item" : "items"}`;
|
|
2024
|
+
if (min === 0) return `expected at most ${max} matching ${max === 1 ? "item" : "items"}`;
|
|
2025
|
+
return `expected between ${min} and ${max} matching items`;
|
|
2026
|
+
}
|
|
2027
|
+
function pointer(path, key) {
|
|
2028
|
+
return `${path}/${String(key).replace(/~/g, "~0").replace(/\//g, "~1")}`;
|
|
2029
|
+
}
|
|
2030
|
+
function typeName(v) {
|
|
2031
|
+
if (v === null) return "null";
|
|
2032
|
+
if (Array.isArray(v)) return "array";
|
|
2033
|
+
if (v instanceof Uint8Array) return "bytes";
|
|
2034
|
+
if (typeof v === "number" && Number.isInteger(v)) return "integer";
|
|
2035
|
+
return typeof v;
|
|
2036
|
+
}
|
|
2037
|
+
//#endregion
|
|
2038
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+pi-schema@1.5.0/node_modules/@earendil-works/pi-schema/dist/validator.js
|
|
2039
|
+
function compile(schema, options = NO_OPTIONS) {
|
|
2040
|
+
const check = compileCheck(schema, options);
|
|
2041
|
+
return options.coerce === true ? new CoercingValidator(schema, options, check) : new Validator(schema, options, check);
|
|
2042
|
+
}
|
|
2043
|
+
const NO_OPTIONS = Object.freeze({});
|
|
2044
|
+
/** A compiled schema whose valid values have type `T` (`unknown` unless the schema was built with the builders). */
|
|
2045
|
+
var Validator = class {
|
|
2046
|
+
/** Whether `value` is valid. A plain function: it may be passed around without its validator. */
|
|
2047
|
+
check;
|
|
2048
|
+
schema;
|
|
2049
|
+
options;
|
|
2050
|
+
explainer = void 0;
|
|
2051
|
+
constructor(schema, options, check) {
|
|
2052
|
+
this.check = check;
|
|
2053
|
+
this.schema = schema;
|
|
2054
|
+
this.options = options;
|
|
2055
|
+
}
|
|
2056
|
+
/**
|
|
2057
|
+
* Why `value` is invalid: one error per failing keyword, `[]` when it is valid. Built on the first failure and
|
|
2058
|
+
* kept, so a validator whose values always pass never pays for it.
|
|
2059
|
+
*/
|
|
2060
|
+
errors(value) {
|
|
2061
|
+
if (this.check(value)) return [];
|
|
2062
|
+
this.explainer ??= new Explainer(compiler(this.schema, this.options), this.schema);
|
|
2063
|
+
return this.explainer.errors(value);
|
|
2064
|
+
}
|
|
2065
|
+
};
|
|
2066
|
+
/** A validator compiled with `coerce: true`: it also coerces loosely typed input towards the schema. */
|
|
2067
|
+
var CoercingValidator = class extends Validator {
|
|
2068
|
+
coercer = void 0;
|
|
2069
|
+
/**
|
|
2070
|
+
* `value` coerced towards the schema: numeric strings to numbers, `"true"` to `true`, a single value to a one-item
|
|
2071
|
+
* array, an optional `null` dropped, the first union branch the value converts to (the README lists every rule).
|
|
2072
|
+
* Only the changed paths are copied; `value` comes back itself when nothing changes, and is never modified. Values
|
|
2073
|
+
* that cannot be coerced stay as they are. The rules are built on the first call.
|
|
2074
|
+
*/
|
|
2075
|
+
coerce(value) {
|
|
2076
|
+
this.coercer ??= new Coercer(compiler(this.schema, this.options), this.schema);
|
|
2077
|
+
return this.coercer.coerce(value);
|
|
2078
|
+
}
|
|
2079
|
+
/** Coerces `value`, then checks it: the coerced value when it is valid, else its errors. */
|
|
2080
|
+
parse(value) {
|
|
2081
|
+
const coerced = this.coerce(value);
|
|
2082
|
+
return this.check(coerced) ? {
|
|
2083
|
+
ok: true,
|
|
2084
|
+
value: coerced
|
|
2085
|
+
} : {
|
|
2086
|
+
ok: false,
|
|
2087
|
+
errors: this.errors(coerced)
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
};
|
|
2091
|
+
function compileCheck(schema, options) {
|
|
2092
|
+
return compiler(schema, options).root();
|
|
2093
|
+
}
|
|
2094
|
+
function compiler(schema, options) {
|
|
2095
|
+
const plain = new Compiler(schema, options, false);
|
|
2096
|
+
try {
|
|
2097
|
+
plain.root();
|
|
2098
|
+
return plain;
|
|
2099
|
+
} catch (error) {
|
|
2100
|
+
if (error !== RESTART) throw error;
|
|
2101
|
+
return new Compiler(schema, options, true);
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
//#endregion
|
|
2105
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+chord@1.5.0_esbuild@0.28.2/node_modules/@earendil-works/chord/dist/errors.js
|
|
2106
|
+
/** Error codes callers see (guide table). A refused or aborted reload keeps the code of its cause. */
|
|
2107
|
+
const CHORD_ERROR_CODES = [
|
|
2108
|
+
"aborted",
|
|
2109
|
+
"contract_mismatch",
|
|
2110
|
+
"forbidden",
|
|
2111
|
+
"gone",
|
|
2112
|
+
"invalid",
|
|
2113
|
+
"not_in_variant",
|
|
2114
|
+
"not_ready",
|
|
2115
|
+
"released",
|
|
2116
|
+
"superseded",
|
|
2117
|
+
"unavailable",
|
|
2118
|
+
"upgrade_conflict",
|
|
2119
|
+
"upgrade_required"
|
|
2120
|
+
];
|
|
2121
|
+
const RETRYABLE = /* @__PURE__ */ new Set(["superseded", "upgrade_conflict"]);
|
|
2122
|
+
var ChordError = class extends Error {
|
|
2123
|
+
code;
|
|
2124
|
+
reason;
|
|
2125
|
+
retryable;
|
|
2126
|
+
details;
|
|
2127
|
+
constructor(code, message, options) {
|
|
2128
|
+
super(`${code}${options?.reason ? `/${options.reason}` : ""}: ${message}`, { cause: options?.cause });
|
|
2129
|
+
this.name = "ChordError";
|
|
2130
|
+
this.code = code;
|
|
2131
|
+
this.reason = options?.reason;
|
|
2132
|
+
this.retryable = RETRYABLE.has(code);
|
|
2133
|
+
this.details = options?.details;
|
|
2134
|
+
}
|
|
2135
|
+
};
|
|
2136
|
+
const isChordError = (error, code) => error instanceof ChordError && (code === void 0 || error.code === code);
|
|
2137
|
+
/** For factories and methods refusing a principal: `throw forbidden()`. */
|
|
2138
|
+
const forbidden = (message = "forbidden") => new ChordError("forbidden", message);
|
|
2139
|
+
const invalid = (reason, message, details) => new ChordError("invalid", message, {
|
|
2140
|
+
reason,
|
|
2141
|
+
details
|
|
2142
|
+
});
|
|
2143
|
+
/** Keeps a ChordError's code; anything else becomes `unavailable` with the original as cause. */
|
|
2144
|
+
const asChordError = (error, context) => error instanceof ChordError ? error : new ChordError("unavailable", `${context}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
2145
|
+
/** Runs every step, then throws one error, or an AggregateError when several failed. */
|
|
2146
|
+
async function runAll(steps, message) {
|
|
2147
|
+
const errors = [];
|
|
2148
|
+
for (const step of steps) try {
|
|
2149
|
+
await step();
|
|
2150
|
+
} catch (error) {
|
|
2151
|
+
errors.push(error);
|
|
2152
|
+
}
|
|
2153
|
+
if (errors.length === 1) throw errors[0];
|
|
2154
|
+
if (errors.length > 1) throw new AggregateError(errors, message);
|
|
2155
|
+
}
|
|
2156
|
+
//#endregion
|
|
2157
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+chord@1.5.0_esbuild@0.28.2/node_modules/@earendil-works/chord/dist/schema.js
|
|
2158
|
+
const asSchema = (schema) => schema !== null && typeof schema === "object" ? schema : schema === false ? { not: {} } : {};
|
|
2159
|
+
/** Canonical JSON: sorted object keys, `undefined` members dropped. */
|
|
2160
|
+
function canonicalJson(value) {
|
|
2161
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "null";
|
|
2162
|
+
if (Array.isArray(value)) return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
|
|
2163
|
+
return `{${Object.keys(value).filter((key) => value[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
|
|
2164
|
+
}
|
|
2165
|
+
/** Non-cryptographic 64-bit hash (two FNV-1a lanes). Contracts are trusted, so collisions are not an attack surface. */
|
|
2166
|
+
function hash64(text) {
|
|
2167
|
+
let a = 2166136261;
|
|
2168
|
+
let b = 1523705862;
|
|
2169
|
+
for (let index = 0; index < text.length; index++) {
|
|
2170
|
+
const code = text.charCodeAt(index);
|
|
2171
|
+
a = Math.imul(a ^ code, 16777619);
|
|
2172
|
+
b = Math.imul(b ^ code, 1540483477) ^ b >>> 13;
|
|
2173
|
+
}
|
|
2174
|
+
return (a >>> 0).toString(16).padStart(8, "0") + (b >>> 0).toString(16).padStart(8, "0");
|
|
2175
|
+
}
|
|
2176
|
+
function deepEqual(a, b) {
|
|
2177
|
+
return a === b || canonicalJson(a) === canonicalJson(b);
|
|
2178
|
+
}
|
|
2179
|
+
const validators = /* @__PURE__ */ new WeakMap();
|
|
2180
|
+
/** The compiled validator of `schema`, compiled once per schema object; `format` is an annotation. */
|
|
2181
|
+
function validatorOf(schema) {
|
|
2182
|
+
if (typeof schema === "boolean") return compile(schema);
|
|
2183
|
+
let validator = validators.get(schema);
|
|
2184
|
+
if (validator === void 0) {
|
|
2185
|
+
validator = compile(schema);
|
|
2186
|
+
validators.set(schema, validator);
|
|
2187
|
+
}
|
|
2188
|
+
return validator;
|
|
2189
|
+
}
|
|
2190
|
+
/** Whether `value` matches `schema`. */
|
|
2191
|
+
function isValid(schema, value) {
|
|
2192
|
+
return validatorOf(schema).check(value);
|
|
2193
|
+
}
|
|
2194
|
+
/** Throws `invalid` (with `reason`) and the first schema errors when `value` does not match. */
|
|
2195
|
+
function assertValid(reason, what, schema, value) {
|
|
2196
|
+
const validator = validatorOf(schema);
|
|
2197
|
+
if (validator.check(value)) return;
|
|
2198
|
+
const errors = validator.errors(value).slice(0, 3);
|
|
2199
|
+
const summary = errors.map((error) => `${error.path || "/"} ${error.message}`).join("; ");
|
|
2200
|
+
throw invalid(reason, `${what}: ${summary}`, errors);
|
|
2201
|
+
}
|
|
2202
|
+
/** Applies defaults, strips unknown fields, validates. Returns a fresh value. */
|
|
2203
|
+
function normalize(schema, value, what) {
|
|
2204
|
+
const normalized = cleanFrom(asSchema(schema), withDefaults(asSchema(schema), cloneData(value ?? {})));
|
|
2205
|
+
assertValid("input", what, schema, normalized);
|
|
2206
|
+
return normalized;
|
|
2207
|
+
}
|
|
2208
|
+
/** A copy of `value` with only what `schema` knows: unknown object fields dropped, recursively (TypeBox's `Clean`). */
|
|
2209
|
+
function cleaned(schema, value) {
|
|
2210
|
+
return cleanFrom(asSchema(schema), cloneData(value));
|
|
2211
|
+
}
|
|
2212
|
+
/** A deep copy of plain data: arrays, plain objects and bytes are copied, any other value is kept. */
|
|
2213
|
+
function cloneData(value) {
|
|
2214
|
+
if (Array.isArray(value)) return value.map(cloneData);
|
|
2215
|
+
if (value instanceof Uint8Array) return value.slice();
|
|
2216
|
+
if (value === null || typeof value !== "object") return value;
|
|
2217
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2218
|
+
if (prototype !== Object.prototype && prototype !== null) return value;
|
|
2219
|
+
const copy = {};
|
|
2220
|
+
for (const [key, item] of Object.entries(value)) copy[key] = cloneData(item);
|
|
2221
|
+
return copy;
|
|
2222
|
+
}
|
|
2223
|
+
const isPlainObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Uint8Array);
|
|
2224
|
+
const isSchemaObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2225
|
+
/** The object an `allOf` of object schemas evaluates to (TypeBox's `Evaluate`), or undefined for any other `allOf`. */
|
|
2226
|
+
function mergedAllOf(schema) {
|
|
2227
|
+
if (!Array.isArray(schema.allOf) || !schema.allOf.every((branch) => isSchemaObject(branch.properties))) return void 0;
|
|
2228
|
+
const properties = {};
|
|
2229
|
+
const required = /* @__PURE__ */ new Set();
|
|
2230
|
+
for (const branch of schema.allOf) {
|
|
2231
|
+
Object.assign(properties, branch.properties);
|
|
2232
|
+
for (const key of branch.required ?? []) required.add(key);
|
|
2233
|
+
}
|
|
2234
|
+
return {
|
|
2235
|
+
type: "object",
|
|
2236
|
+
properties,
|
|
2237
|
+
required: [...required],
|
|
2238
|
+
...schema.unevaluatedProperties === void 0 ? {} : { additionalProperties: schema.unevaluatedProperties }
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
/** The pattern and value schema of a record (`patternProperties` with one pattern). */
|
|
2242
|
+
function recordOf(schema) {
|
|
2243
|
+
if (!isSchemaObject(schema.patternProperties) || isSchemaObject(schema.properties)) return void 0;
|
|
2244
|
+
const [entry] = Object.entries(schema.patternProperties);
|
|
2245
|
+
return entry === void 0 ? void 0 : [new RegExp(entry[0], "u"), entry[1]];
|
|
2246
|
+
}
|
|
2247
|
+
/** Whether `additional` (an object's `additionalProperties`) keeps an unknown field holding `value`. */
|
|
2248
|
+
const keepsUnknown = (additional, value) => additional === true || isSchemaObject(additional) && isValid(additional, value);
|
|
2249
|
+
function cleanFrom(schema, value) {
|
|
2250
|
+
const merged = mergedAllOf(schema);
|
|
2251
|
+
if (merged !== void 0) return cleanFrom(merged, value);
|
|
2252
|
+
if (Array.isArray(schema.anyOf)) {
|
|
2253
|
+
for (const branch of schema.anyOf) {
|
|
2254
|
+
const candidate = cleanFrom(asSchema(branch), cloneData(value));
|
|
2255
|
+
if (isValid(asSchema(branch), candidate)) return candidate;
|
|
2256
|
+
}
|
|
2257
|
+
return value;
|
|
2258
|
+
}
|
|
2259
|
+
if (Array.isArray(value)) {
|
|
2260
|
+
const prefix = Array.isArray(schema.items) ? schema.items : Array.isArray(schema.prefixItems) ? schema.prefixItems : void 0;
|
|
2261
|
+
if (prefix !== void 0) {
|
|
2262
|
+
const length = Math.min(value.length, prefix.length);
|
|
2263
|
+
for (let index = 0; index < length; index++) value[index] = cleanFrom(asSchema(prefix[index]), value[index]);
|
|
2264
|
+
return value.length > length ? value.slice(0, length) : value;
|
|
2265
|
+
}
|
|
2266
|
+
if (isSchemaObject(schema.items)) return value.map((item) => cleanFrom(schema.items, item));
|
|
2267
|
+
return value;
|
|
2268
|
+
}
|
|
2269
|
+
if (!isPlainObject(value)) return value;
|
|
2270
|
+
const record = recordOf(schema);
|
|
2271
|
+
const properties = isSchemaObject(schema.properties) ? schema.properties : void 0;
|
|
2272
|
+
if (properties === void 0 && record === void 0 && !isSchemaObject(schema.additionalProperties)) return value;
|
|
2273
|
+
for (const key of Object.keys(value)) {
|
|
2274
|
+
const matched = (properties !== void 0 && Object.hasOwn(properties, key) ? properties[key] : void 0) ?? (record?.[0].test(key) ? record[1] : void 0);
|
|
2275
|
+
if (matched !== void 0) value[key] = cleanFrom(asSchema(matched), value[key]);
|
|
2276
|
+
else if (keepsUnknown(schema.additionalProperties, value[key])) value[key] = cleanFrom(asSchema(schema.additionalProperties), value[key]);
|
|
2277
|
+
else delete value[key];
|
|
2278
|
+
}
|
|
2279
|
+
return value;
|
|
2280
|
+
}
|
|
2281
|
+
function withDefaults(schema, value) {
|
|
2282
|
+
const defaulted = value === void 0 && "default" in schema ? cloneData(schema.default) : value;
|
|
2283
|
+
const merged = mergedAllOf(schema);
|
|
2284
|
+
if (merged !== void 0) return withDefaults(merged, defaulted);
|
|
2285
|
+
if (Array.isArray(schema.anyOf)) {
|
|
2286
|
+
for (const branch of schema.anyOf) {
|
|
2287
|
+
const candidate = withDefaults(asSchema(branch), cloneData(defaulted));
|
|
2288
|
+
if (isValid(asSchema(branch), candidate)) return candidate;
|
|
2289
|
+
}
|
|
2290
|
+
return defaulted;
|
|
2291
|
+
}
|
|
2292
|
+
if (Array.isArray(defaulted)) {
|
|
2293
|
+
const prefix = Array.isArray(schema.items) ? schema.items : Array.isArray(schema.prefixItems) ? schema.prefixItems : void 0;
|
|
2294
|
+
if (prefix !== void 0) {
|
|
2295
|
+
for (let index = 0; index < prefix.length; index++) {
|
|
2296
|
+
const item = withDefaults(asSchema(prefix[index]), defaulted[index]);
|
|
2297
|
+
if (index < defaulted.length || item !== void 0) defaulted[index] = item;
|
|
2298
|
+
}
|
|
2299
|
+
return defaulted;
|
|
2300
|
+
}
|
|
2301
|
+
if (isSchemaObject(schema.items)) return defaulted.map((item) => withDefaults(schema.items, item));
|
|
2302
|
+
return defaulted;
|
|
2303
|
+
}
|
|
2304
|
+
if (!isPlainObject(defaulted)) return defaulted;
|
|
2305
|
+
const properties = isSchemaObject(schema.properties) ? schema.properties : void 0;
|
|
2306
|
+
const record = recordOf(schema);
|
|
2307
|
+
if (properties !== void 0) {
|
|
2308
|
+
const required = schema.required ?? [];
|
|
2309
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
2310
|
+
const item = withDefaults(asSchema(property), defaulted[key]);
|
|
2311
|
+
if (item === void 0 && (!required.includes(key) || !("default" in asSchema(property)))) continue;
|
|
2312
|
+
defaulted[key] = item;
|
|
2313
|
+
}
|
|
2314
|
+
} else if (record !== void 0 && isSchemaObject(record[1]) && "default" in record[1]) {
|
|
2315
|
+
for (const key of Object.keys(defaulted)) if (record[0].test(key)) defaulted[key] = withDefaults(record[1], defaulted[key]);
|
|
2316
|
+
}
|
|
2317
|
+
if (!isSchemaObject(schema.additionalProperties)) return defaulted;
|
|
2318
|
+
for (const key of Object.keys(defaulted)) if (!(properties !== void 0 && Object.hasOwn(properties, key)) && !record?.[0].test(key)) defaulted[key] = withDefaults(schema.additionalProperties, defaulted[key]);
|
|
2319
|
+
return defaulted;
|
|
2320
|
+
}
|
|
2321
|
+
/** Canonical identity of a normalized value: fields equal to their schema default are omitted. */
|
|
2322
|
+
function canonicalIdentity(schema, value) {
|
|
2323
|
+
return canonicalJson(stripDefaults(asSchema(schema), value));
|
|
2324
|
+
}
|
|
2325
|
+
function stripDefaults(schema, value) {
|
|
2326
|
+
if (Array.isArray(value)) {
|
|
2327
|
+
const items = schema.items;
|
|
2328
|
+
if (Array.isArray(items)) return value.map((item, index) => stripDefaults(asSchema(items[index]), item));
|
|
2329
|
+
return value.map((item) => stripDefaults(asSchema(items), item));
|
|
2330
|
+
}
|
|
2331
|
+
if (value === null || typeof value !== "object") return value;
|
|
2332
|
+
const properties = asSchema(schema.properties);
|
|
2333
|
+
const result = {};
|
|
2334
|
+
for (const [key, item] of Object.entries(value)) {
|
|
2335
|
+
const property = asSchema(properties[key]);
|
|
2336
|
+
if ("default" in property && deepEqual(property.default, item)) continue;
|
|
2337
|
+
result[key] = stripDefaults(property, item);
|
|
2338
|
+
}
|
|
2339
|
+
return result;
|
|
2340
|
+
}
|
|
2341
|
+
const CONSTRAINTS = [
|
|
2342
|
+
"minLength",
|
|
2343
|
+
"maxLength",
|
|
2344
|
+
"pattern",
|
|
2345
|
+
"format",
|
|
2346
|
+
"minimum",
|
|
2347
|
+
"maximum",
|
|
2348
|
+
"exclusiveMinimum",
|
|
2349
|
+
"exclusiveMaximum",
|
|
2350
|
+
"multipleOf",
|
|
2351
|
+
"minItems",
|
|
2352
|
+
"maxItems",
|
|
2353
|
+
"uniqueItems",
|
|
2354
|
+
"minProperties",
|
|
2355
|
+
"maxProperties"
|
|
2356
|
+
];
|
|
2357
|
+
const typesOf = (schema) => typeof schema.type === "string" ? [schema.type] : Array.isArray(schema.type) ? schema.type : void 0;
|
|
2358
|
+
/** Keywords `fits` reasons about. Any other validation keyword in the provider's schema forces exact equality. */
|
|
2359
|
+
const KNOWN = /* @__PURE__ */ new Set([
|
|
2360
|
+
...CONSTRAINTS,
|
|
2361
|
+
"type",
|
|
2362
|
+
"properties",
|
|
2363
|
+
"required",
|
|
2364
|
+
"additionalProperties",
|
|
2365
|
+
"patternProperties",
|
|
2366
|
+
"items",
|
|
2367
|
+
"additionalItems",
|
|
2368
|
+
"const",
|
|
2369
|
+
"enum",
|
|
2370
|
+
"anyOf",
|
|
2371
|
+
"parameters",
|
|
2372
|
+
"returnType"
|
|
2373
|
+
]);
|
|
2374
|
+
/** Annotations: no effect on validity. */
|
|
2375
|
+
const ANNOTATIONS = /* @__PURE__ */ new Set([
|
|
2376
|
+
"title",
|
|
2377
|
+
"description",
|
|
2378
|
+
"default",
|
|
2379
|
+
"examples",
|
|
2380
|
+
"$id",
|
|
2381
|
+
"$schema",
|
|
2382
|
+
"$comment",
|
|
2383
|
+
"readOnly",
|
|
2384
|
+
"writeOnly",
|
|
2385
|
+
"deprecated"
|
|
2386
|
+
]);
|
|
2387
|
+
const withoutAnnotations = (schema) => Object.fromEntries(Object.entries(schema).filter(([key]) => !ANNOTATIONS.has(key)));
|
|
2388
|
+
/**
|
|
2389
|
+
* Conservative structural subtyping: true only if every value valid under `sub` is valid under `sup`, where object
|
|
2390
|
+
* fields missing from `sub` but optional in `sup` count as fine (unknown fields are stripped at the provider, see
|
|
2391
|
+
* `RecordImpl.call`). A provider schema using a keyword this function does not model (`not`, `allOf`, `contains`,
|
|
2392
|
+
* `$ref`, ...) or an `additionalProperties` schema only fits an identical consumer schema.
|
|
2393
|
+
*/
|
|
2394
|
+
function fits(subSchema, supSchema) {
|
|
2395
|
+
const sub = withoutAnnotations(asSchema(subSchema));
|
|
2396
|
+
const sup = withoutAnnotations(asSchema(supSchema));
|
|
2397
|
+
if (Object.keys(sup).length === 0) return true;
|
|
2398
|
+
if (deepEqual(sub, sup)) return true;
|
|
2399
|
+
if (Object.keys(sup).some((key) => !KNOWN.has(key))) return false;
|
|
2400
|
+
if (sup.additionalProperties !== void 0 && typeof sup.additionalProperties !== "boolean") return false;
|
|
2401
|
+
if (Array.isArray(sub.anyOf)) return sub.anyOf.every((branch) => fits(branch, sup));
|
|
2402
|
+
if (Array.isArray(sup.anyOf)) return sup.anyOf.some((branch) => fits(sub, branch));
|
|
2403
|
+
if ("const" in sup) return "const" in sub && deepEqual(sub.const, sup.const);
|
|
2404
|
+
if (Array.isArray(sup.enum)) return ("const" in sub ? [sub.const] : Array.isArray(sub.enum) ? sub.enum : void 0)?.every((item) => sup.enum.some((allowed) => deepEqual(allowed, item))) ?? false;
|
|
2405
|
+
for (const key of CONSTRAINTS) if (key in sup && !deepEqual(sub[key], sup[key])) return false;
|
|
2406
|
+
const supTypes = typesOf(sup);
|
|
2407
|
+
const subTypes = typesOf(sub);
|
|
2408
|
+
if (supTypes === void 0 || subTypes === void 0) return false;
|
|
2409
|
+
if (!subTypes.every((type) => supTypes.includes(type) || type === "integer" && supTypes.includes("number"))) return false;
|
|
2410
|
+
if ("const" in sub || Array.isArray(sub.enum)) return true;
|
|
2411
|
+
if (subTypes.includes("object") && !objectFits(sub, sup)) return false;
|
|
2412
|
+
if (subTypes.includes("array") && !arrayFits(sub, sup)) return false;
|
|
2413
|
+
if (subTypes.includes("function")) return functionFits(sub, sup);
|
|
2414
|
+
return true;
|
|
2415
|
+
}
|
|
2416
|
+
function objectFits(sub, sup) {
|
|
2417
|
+
const subProperties = asSchema(sub.properties);
|
|
2418
|
+
const supProperties = asSchema(sup.properties);
|
|
2419
|
+
const subRequired = new Set(sub.required ?? []);
|
|
2420
|
+
for (const key of sup.required ?? []) if (!subRequired.has(key)) return false;
|
|
2421
|
+
for (const [key, property] of Object.entries(supProperties)) if (key in subProperties) {
|
|
2422
|
+
if (!fits(subProperties[key], property)) return false;
|
|
2423
|
+
} else if (typeof sub.additionalProperties === "object" && !fits(sub.additionalProperties, property)) return false;
|
|
2424
|
+
if (sup.additionalProperties === false) {
|
|
2425
|
+
if (sub.additionalProperties !== false) return false;
|
|
2426
|
+
if (Object.keys(subProperties).some((key) => !(key in supProperties))) return false;
|
|
2427
|
+
}
|
|
2428
|
+
const supPatterns = asSchema(sup.patternProperties);
|
|
2429
|
+
if (Object.keys(supPatterns).length > 0) {
|
|
2430
|
+
const subPatterns = asSchema(sub.patternProperties);
|
|
2431
|
+
if (sub.additionalProperties !== false && Object.keys(subPatterns).length === 0) return false;
|
|
2432
|
+
for (const [pattern, property] of Object.entries(supPatterns)) {
|
|
2433
|
+
const matcher = new RegExp(pattern, "u");
|
|
2434
|
+
for (const [key, subProperty] of Object.entries(subProperties)) if (!(key in supProperties) && matcher.test(key) && !fits(subProperty, property)) return false;
|
|
2435
|
+
if (Object.keys(subPatterns).length > 0 && (!(pattern in subPatterns) || !fits(subPatterns[pattern], property))) return false;
|
|
2436
|
+
}
|
|
2437
|
+
for (const pattern of Object.keys(subPatterns)) if (!(pattern in supPatterns)) return false;
|
|
2438
|
+
}
|
|
2439
|
+
return true;
|
|
2440
|
+
}
|
|
2441
|
+
function arrayFits(sub, sup) {
|
|
2442
|
+
if (Array.isArray(sup.items)) {
|
|
2443
|
+
if (!Array.isArray(sub.items) || sub.items.length !== sup.items.length) return false;
|
|
2444
|
+
return sub.items.every((item, index) => fits(item, sup.items[index]));
|
|
2445
|
+
}
|
|
2446
|
+
if (Array.isArray(sub.items)) return sub.items.every((item) => fits(item, sup.items));
|
|
2447
|
+
return fits(sub.items, sup.items);
|
|
2448
|
+
}
|
|
2449
|
+
function functionFits(sub, sup) {
|
|
2450
|
+
const subParameters = sub.parameters ?? [];
|
|
2451
|
+
const supParameters = sup.parameters ?? [];
|
|
2452
|
+
if (subParameters.length > supParameters.length) return false;
|
|
2453
|
+
if (!subParameters.every((parameter, index) => fits(supParameters[index], parameter))) return false;
|
|
2454
|
+
return fits(sub.returnType, sup.returnType);
|
|
2455
|
+
}
|
|
2456
|
+
//#endregion
|
|
2457
|
+
//#region ../../../node_modules/.pnpm/@earendil-works+chord@1.5.0_esbuild@0.28.2/node_modules/@earendil-works/chord/dist/contract.js
|
|
2458
|
+
const MEMBER = Symbol("chord.member");
|
|
2459
|
+
function method(args, result) {
|
|
2460
|
+
return {
|
|
2461
|
+
[MEMBER]: "method",
|
|
2462
|
+
args,
|
|
2463
|
+
result
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
/** A native in-process object identified by `name@version` (local contracts only). */
|
|
2467
|
+
const opaque = (id) => {
|
|
2468
|
+
if (!/^[^@\s]+@\d+$/.test(id)) throw new TypeError(`opaque id must be name@version: ${id}`);
|
|
2469
|
+
return {
|
|
2470
|
+
[MEMBER]: "opaque",
|
|
2471
|
+
id
|
|
2472
|
+
};
|
|
2473
|
+
};
|
|
2474
|
+
/** Objects of the type live on the host named `name` (`hostNamed("server")`). */
|
|
2475
|
+
function hostNamed(name) {
|
|
2476
|
+
if (typeof name !== "string" || name === "") throw new TypeError("hostNamed needs a host name");
|
|
2477
|
+
return { name };
|
|
2478
|
+
}
|
|
2479
|
+
/** The host an object of `placement` with this (normalized) input lives on. Throws `invalid/placement`. */
|
|
2480
|
+
function resolveHost(typeName, placement, input) {
|
|
2481
|
+
if ("name" in placement) return placement.name;
|
|
2482
|
+
const value = input !== null && typeof input === "object" ? input[placement.key] : void 0;
|
|
2483
|
+
if (typeof value !== "string" || value === "") throw invalid("placement", `${typeName}: input field ${placement.key} names no host`);
|
|
2484
|
+
return placement.prefix + value;
|
|
2485
|
+
}
|
|
2486
|
+
/** Whether the host named `hostName` may serve a type of `placement`. */
|
|
2487
|
+
const placedOn = (placement, hostName) => "name" in placement ? placement.name === hostName : hostName.startsWith(placement.prefix) && hostName.length > placement.prefix.length;
|
|
2488
|
+
const placementText = (placement) => "name" in placement ? placement.name : `${placement.prefix}<${placement.key}>`;
|
|
2489
|
+
const SchemaObject = obj({}, { open: true });
|
|
2490
|
+
const MemberDescriptionSchema = union([
|
|
2491
|
+
obj({
|
|
2492
|
+
kind: lit("method"),
|
|
2493
|
+
args: opt(SchemaObject),
|
|
2494
|
+
result: opt(SchemaObject)
|
|
2495
|
+
}, { open: true }),
|
|
2496
|
+
obj({
|
|
2497
|
+
kind: lit("state"),
|
|
2498
|
+
schema: SchemaObject
|
|
2499
|
+
}, { open: true }),
|
|
2500
|
+
obj({
|
|
2501
|
+
kind: lit("opaque"),
|
|
2502
|
+
id: str()
|
|
2503
|
+
}, { open: true })
|
|
2504
|
+
]);
|
|
2505
|
+
const PlacementSchema = union([obj({ name: str({ minLength: 1 }) }), obj({
|
|
2506
|
+
prefix: str({ minLength: 1 }),
|
|
2507
|
+
key: str({ minLength: 1 })
|
|
2508
|
+
})]);
|
|
2509
|
+
const DescriptionSchema = obj({
|
|
2510
|
+
name: str({ minLength: 1 }),
|
|
2511
|
+
scope: union([lit("remote"), lit("local")]),
|
|
2512
|
+
version: int(),
|
|
2513
|
+
input: SchemaObject,
|
|
2514
|
+
/** Remote types only (required there): where their objects live. */
|
|
2515
|
+
host: opt(PlacementSchema),
|
|
2516
|
+
variants: map(map(MemberDescriptionSchema))
|
|
2517
|
+
}, { open: true });
|
|
2518
|
+
/** Names a reference uses itself; members may not use them. */
|
|
2519
|
+
const RESERVED_MEMBERS = /* @__PURE__ */ new Set([
|
|
2520
|
+
"variant",
|
|
2521
|
+
"status",
|
|
2522
|
+
"ready",
|
|
2523
|
+
"shape",
|
|
2524
|
+
"error",
|
|
2525
|
+
"onShape",
|
|
2526
|
+
"onStatus",
|
|
2527
|
+
"release",
|
|
2528
|
+
"then",
|
|
2529
|
+
"contract"
|
|
2530
|
+
]);
|
|
2531
|
+
function describeMember(name, member, scope) {
|
|
2532
|
+
if (RESERVED_MEMBERS.has(name)) throw new TypeError(`member name is reserved: ${name}`);
|
|
2533
|
+
const brand = member[MEMBER];
|
|
2534
|
+
if (brand === "method") {
|
|
2535
|
+
const spec = member;
|
|
2536
|
+
return {
|
|
2537
|
+
kind: "method",
|
|
2538
|
+
...spec.args === void 0 ? {} : { args: spec.args },
|
|
2539
|
+
...spec.result === void 0 ? {} : { result: spec.result }
|
|
2540
|
+
};
|
|
2541
|
+
}
|
|
2542
|
+
if (brand === "opaque") {
|
|
2543
|
+
if (scope === "remote") throw new TypeError(`remote contracts cannot expose opaque members: ${name}`);
|
|
2544
|
+
return {
|
|
2545
|
+
kind: "opaque",
|
|
2546
|
+
id: member.id
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
return {
|
|
2550
|
+
kind: "state",
|
|
2551
|
+
schema: member
|
|
2552
|
+
};
|
|
2553
|
+
}
|
|
2554
|
+
function finish(contract) {
|
|
2555
|
+
return {
|
|
2556
|
+
...contract,
|
|
2557
|
+
fingerprint: hash64(canonicalJson(contract.description))
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
function checkHeader(name, version) {
|
|
2561
|
+
if (!name) throw new TypeError("contract name is empty");
|
|
2562
|
+
if (!Number.isInteger(version) || version < 1) throw new TypeError(`contract version must be a positive integer`);
|
|
2563
|
+
}
|
|
2564
|
+
function remote(name, def) {
|
|
2565
|
+
checkHeader(name, def.version);
|
|
2566
|
+
const placement = def.host;
|
|
2567
|
+
if (placement === void 0 || !isValid(PlacementSchema, placement)) throw new TypeError(`remote contract ${name} needs \`host\`: hostNamed(…) or hostFamily(…)`);
|
|
2568
|
+
const host = "name" in placement ? { name: placement.name } : {
|
|
2569
|
+
prefix: placement.prefix,
|
|
2570
|
+
key: placement.key
|
|
2571
|
+
};
|
|
2572
|
+
const variants = {};
|
|
2573
|
+
if (Object.keys(def.variants).length === 0) throw new TypeError(`remote contract ${name} has no variants`);
|
|
2574
|
+
for (const [kind, variant] of Object.entries(def.variants)) {
|
|
2575
|
+
const members = {};
|
|
2576
|
+
for (const [key, schema] of Object.entries(variant.state ?? {})) members[key] = describeMember(key, schema, "remote");
|
|
2577
|
+
for (const [key, spec] of Object.entries(variant.methods ?? {})) {
|
|
2578
|
+
if (key in members) throw new TypeError(`member ${key} is both state and method in ${name}.${kind}`);
|
|
2579
|
+
members[key] = describeMember(key, spec, "remote");
|
|
2580
|
+
if (members[key].kind !== "method") throw new TypeError(`methods.${key} is not a method()`);
|
|
2581
|
+
}
|
|
2582
|
+
variants[kind] = members;
|
|
2583
|
+
}
|
|
2584
|
+
const description = {
|
|
2585
|
+
name,
|
|
2586
|
+
scope: "remote",
|
|
2587
|
+
version: def.version,
|
|
2588
|
+
input: def.input,
|
|
2589
|
+
host,
|
|
2590
|
+
variants
|
|
2591
|
+
};
|
|
2592
|
+
return finish({
|
|
2593
|
+
scope: "remote",
|
|
2594
|
+
name,
|
|
2595
|
+
version: def.version,
|
|
2596
|
+
input: def.input,
|
|
2597
|
+
def,
|
|
2598
|
+
description
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
function local(name, def) {
|
|
2602
|
+
checkHeader(name, def.version);
|
|
2603
|
+
const members = {};
|
|
2604
|
+
for (const [key, member] of Object.entries(def.members ?? {})) members[key] = describeMember(key, member, "local");
|
|
2605
|
+
const description = {
|
|
2606
|
+
name,
|
|
2607
|
+
scope: "local",
|
|
2608
|
+
version: def.version,
|
|
2609
|
+
input: def.input,
|
|
2610
|
+
variants: { [""]: members }
|
|
2611
|
+
};
|
|
2612
|
+
return finish({
|
|
2613
|
+
scope: "local",
|
|
2614
|
+
name,
|
|
2615
|
+
version: def.version,
|
|
2616
|
+
input: def.input,
|
|
2617
|
+
def,
|
|
2618
|
+
description
|
|
2619
|
+
});
|
|
2620
|
+
}
|
|
2621
|
+
/**
|
|
2622
|
+
* A consumer token received over a link (only its description travels). Has no `def`, so it is only good for binding
|
|
2623
|
+
* and validation, never for TypeScript types.
|
|
2624
|
+
*/
|
|
2625
|
+
function contractFromDescription(description) {
|
|
2626
|
+
const { name, scope, version, input, host } = description;
|
|
2627
|
+
if (typeof name !== "string" || scope !== "remote" && scope !== "local" || !Number.isInteger(version) || scope === "remote" !== (host !== void 0)) throw new ChordError("invalid", "malformed contract token", { reason: "token" });
|
|
2628
|
+
const base = {
|
|
2629
|
+
name,
|
|
2630
|
+
version,
|
|
2631
|
+
input,
|
|
2632
|
+
description,
|
|
2633
|
+
fingerprint: hash64(canonicalJson(description))
|
|
2634
|
+
};
|
|
2635
|
+
return scope === "remote" ? {
|
|
2636
|
+
...base,
|
|
2637
|
+
scope,
|
|
2638
|
+
def: {
|
|
2639
|
+
version,
|
|
2640
|
+
input,
|
|
2641
|
+
host,
|
|
2642
|
+
variants: {}
|
|
2643
|
+
}
|
|
2644
|
+
} : {
|
|
2645
|
+
...base,
|
|
2646
|
+
scope,
|
|
2647
|
+
def: {
|
|
2648
|
+
version,
|
|
2649
|
+
input
|
|
2650
|
+
}
|
|
2651
|
+
};
|
|
2652
|
+
}
|
|
2653
|
+
/** Returns why `provider` does not cover `consumer`, or undefined when it does. */
|
|
2654
|
+
function coverage(provider, consumer) {
|
|
2655
|
+
if (provider.name !== consumer.name || provider.scope !== consumer.scope) return "different type";
|
|
2656
|
+
if (!samePlacement(provider, consumer)) return "host";
|
|
2657
|
+
if (!fits(consumer.input, provider.input)) return "input";
|
|
2658
|
+
for (const [kind, consumerMembers] of Object.entries(consumer.variants)) {
|
|
2659
|
+
const providerMembers = provider.variants[kind];
|
|
2660
|
+
if (providerMembers === void 0) return `variant ${kind} missing`;
|
|
2661
|
+
for (const [name, wanted] of Object.entries(consumerMembers)) {
|
|
2662
|
+
const offered = providerMembers[name];
|
|
2663
|
+
if (offered === void 0 || offered.kind !== wanted.kind) return `${kind}.${name} missing or of another kind`;
|
|
2664
|
+
if (offered.kind === "method" && wanted.kind === "method") {
|
|
2665
|
+
if (wanted.args === void 0 !== (offered.args === void 0)) return `${kind}.${name} arguments`;
|
|
2666
|
+
if (wanted.args !== void 0 && offered.args !== void 0 && !fits(wanted.args, offered.args)) return `${kind}.${name} arguments`;
|
|
2667
|
+
if (wanted.result !== void 0 && (offered.result === void 0 || !fits(offered.result, wanted.result))) return `${kind}.${name} result`;
|
|
2668
|
+
} else if (offered.kind === "state" && wanted.kind === "state") {
|
|
2669
|
+
if (!fits(offered.schema, wanted.schema)) return `${kind}.${name} state`;
|
|
2670
|
+
} else if (offered.kind === "opaque" && wanted.kind === "opaque" && offered.id !== wanted.id) return `${kind}.${name} opaque ${offered.id} != ${wanted.id}`;
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
const samePlacement = (a, b) => canonicalJson(a.host ?? null) === canonicalJson(b.host ?? null);
|
|
2675
|
+
const placementOf = (description) => description.host === void 0 ? "(local)" : placementText(description.host);
|
|
2676
|
+
/** How a consumer token binds to a provider: directly or through an `accepts` adapter. Throws contract_mismatch. */
|
|
2677
|
+
function bind(provider, accepts, consumer) {
|
|
2678
|
+
if (provider.fingerprint === consumer.fingerprint) return void 0;
|
|
2679
|
+
if (!samePlacement(provider.description, consumer.description)) throw new ChordError("contract_mismatch", `${provider.name} lives on ${placementOf(provider.description)}, the consumer expects ${placementOf(consumer.description)}`);
|
|
2680
|
+
if (provider.version === consumer.version) {
|
|
2681
|
+
const reason = coverage(provider.description, consumer.description);
|
|
2682
|
+
if (reason === void 0) return void 0;
|
|
2683
|
+
throw new ChordError("contract_mismatch", `${provider.name}@${provider.version} does not cover the consumer's description (${reason}); forgotten version bump?`);
|
|
2684
|
+
}
|
|
2685
|
+
const adapter = accepts?.[consumer.version];
|
|
2686
|
+
if (adapter === void 0) throw new ChordError("contract_mismatch", `${provider.name}: provider version ${provider.version}, consumer version ${consumer.version}, no accepts adapter`);
|
|
2687
|
+
return adapter;
|
|
2688
|
+
}
|
|
2689
|
+
/** Whether `contract`'s method `name` takes no arguments (it is called as `ref.name(ctx)`). */
|
|
2690
|
+
function takesNoArgs(contract, name) {
|
|
2691
|
+
for (const members of Object.values(contract.description.variants)) {
|
|
2692
|
+
const member = members[name];
|
|
2693
|
+
if (member?.kind === "method") return member.args === void 0;
|
|
2694
|
+
}
|
|
2695
|
+
return false;
|
|
2696
|
+
}
|
|
2697
|
+
//#endregion
|
|
2698
|
+
//#region ../../core/po-core/src/schemas/protocolContracts.ts
|
|
2699
|
+
/** Name of the Po server host; every Po contract places its objects on it. */
|
|
2700
|
+
const PO_SERVER_HOST = "server";
|
|
2701
|
+
/**
|
|
2702
|
+
* Gives a TypeBox schema the pi-schema type Chord reads. A TypeBox schema is JSON Schema, so Chord validates it
|
|
2703
|
+
* unchanged and contract fingerprints stay the same; only its static type moves.
|
|
2704
|
+
*/
|
|
2705
|
+
function chordSchema(schema) {
|
|
2706
|
+
return schema;
|
|
2707
|
+
}
|
|
2708
|
+
/** `chordSchema` over a variant's state table. */
|
|
2709
|
+
function chordStates(schemas) {
|
|
2710
|
+
return schemas;
|
|
2711
|
+
}
|
|
2712
|
+
/** Chord method specs for a schema table, typed so contracts built from them stay nameable. */
|
|
2713
|
+
function chordMethods(schemas) {
|
|
2714
|
+
return Object.fromEntries(Object.entries(schemas).map(([name, { args, result }]) => [name, result !== void 0 ? method(args && chordSchema(args), chordSchema(result)) : args !== void 0 ? method(chordSchema(args)) : method()]));
|
|
2715
|
+
}
|
|
2716
|
+
//#endregion
|
|
2717
|
+
//#region ../../core/po-core/src/schemas/protocolChannelsContract.ts
|
|
2718
|
+
const Json$4 = Unsafe({});
|
|
2719
|
+
const ChannelFrameSchema = _Object_({
|
|
2720
|
+
type: String$1({ minLength: 1 }),
|
|
2721
|
+
payload: Json$4
|
|
2722
|
+
});
|
|
2723
|
+
/** Latest payload per extension channel frame type. */
|
|
2724
|
+
const PoChannelsStateSchema = Record(String$1(), Json$4);
|
|
2725
|
+
/** A session's extension channels as seen by one connection. */
|
|
2726
|
+
const PoChannelsContract = remote("po.channels", {
|
|
2727
|
+
version: 1,
|
|
2728
|
+
host: hostNamed(PO_SERVER_HOST),
|
|
2729
|
+
input: chordSchema(_Object_({ sessionId: String$1({ minLength: 1 }) })),
|
|
2730
|
+
variants: { default: {
|
|
2731
|
+
state: chordStates({ latest: PoChannelsStateSchema }),
|
|
2732
|
+
methods: chordMethods({ receive: { args: ChannelFrameSchema } })
|
|
2733
|
+
} }
|
|
2734
|
+
});
|
|
2735
|
+
//#endregion
|
|
2736
|
+
//#region ../../core/po-core/src/constants/contextApi.ts
|
|
2737
|
+
/**
|
|
2738
|
+
* What one entry in the composition actually is, for a reader who clicked it.
|
|
2739
|
+
*
|
|
2740
|
+
* The projection prices the composition and stops there: names, owners, and
|
|
2741
|
+
* integer counts, small enough to republish whenever the composition changes.
|
|
2742
|
+
* The prose and the schema behind a figure are an order of magnitude larger and
|
|
2743
|
+
* are wanted one row at a time, so they travel on request instead. This module
|
|
2744
|
+
* is the contract both ends of that request share, and it is deliberately free
|
|
2745
|
+
* of Node imports so a browser can hold it too.
|
|
2746
|
+
*/
|
|
2747
|
+
/** Where a host mounts this package's API; the segment after /api/plugins/. */
|
|
2748
|
+
const API_BASE_PATH = "context";
|
|
2749
|
+
const ITEM_ROUTE = "/item";
|
|
2750
|
+
const CURRENT_ROUTE = "/current";
|
|
2751
|
+
//#endregion
|
|
2752
|
+
//#region ../../core/po-core/src/schemas/httpApiContracts.ts
|
|
2753
|
+
const Text$3 = String$1();
|
|
2754
|
+
const Optional$2 = Optional$4;
|
|
2755
|
+
const Strings$1 = _Array_(Text$3);
|
|
2756
|
+
const Flag$2 = Boolean();
|
|
2757
|
+
const NumberValue$2 = Number$1();
|
|
2758
|
+
const ApiErrorSchema = _Object_({
|
|
2759
|
+
error: Text$3,
|
|
2760
|
+
hash: Optional$2(Text$3)
|
|
2761
|
+
});
|
|
2762
|
+
const ApiOkSchema = _Object_({ ok: Literal(true) });
|
|
2763
|
+
const Json$3 = Unknown({ description: "Value whose schema is supplied by the selected runtime contribution." });
|
|
2764
|
+
/** Common JSON response construction; status and payload remain explicit at the declaration. */
|
|
2765
|
+
function jsonApiResponses(schema, status = 200) {
|
|
2766
|
+
return {
|
|
2767
|
+
[status]: {
|
|
2768
|
+
description: "Successful response",
|
|
2769
|
+
contentType: "application/json",
|
|
2770
|
+
schema
|
|
2771
|
+
},
|
|
2772
|
+
"400": {
|
|
2773
|
+
description: "Invalid request",
|
|
2774
|
+
schema: ApiErrorSchema
|
|
2775
|
+
},
|
|
2776
|
+
"401": {
|
|
2777
|
+
description: "Authentication required",
|
|
2778
|
+
schema: ApiErrorSchema
|
|
2779
|
+
},
|
|
2780
|
+
"403": {
|
|
2781
|
+
description: "Request is not authorized",
|
|
2782
|
+
schema: ApiErrorSchema
|
|
2783
|
+
},
|
|
2784
|
+
"404": {
|
|
2785
|
+
description: "Resource or capability unavailable",
|
|
2786
|
+
schema: ApiErrorSchema
|
|
2787
|
+
},
|
|
2788
|
+
"409": {
|
|
2789
|
+
description: "Conflicting state",
|
|
2790
|
+
schema: ApiErrorSchema
|
|
2791
|
+
},
|
|
2792
|
+
"422": {
|
|
2793
|
+
description: "Invalid operation",
|
|
2794
|
+
schema: ApiErrorSchema
|
|
2795
|
+
},
|
|
2796
|
+
"500": {
|
|
2797
|
+
description: "Host operation failed",
|
|
2798
|
+
schema: ApiErrorSchema
|
|
2799
|
+
},
|
|
2800
|
+
"502": {
|
|
2801
|
+
description: "Provider failed",
|
|
2802
|
+
schema: ApiErrorSchema
|
|
2803
|
+
},
|
|
2804
|
+
"503": {
|
|
2805
|
+
description: "Service unavailable",
|
|
2806
|
+
schema: ApiErrorSchema
|
|
2807
|
+
}
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
const WebCompositionSchema = _Object_({
|
|
2811
|
+
id: Text$3,
|
|
2812
|
+
scope: Union([
|
|
2813
|
+
Literal("global"),
|
|
2814
|
+
Literal("workspace"),
|
|
2815
|
+
Literal("session")
|
|
2816
|
+
]),
|
|
2817
|
+
revision: NumberValue$2,
|
|
2818
|
+
manifestUrl: Text$3,
|
|
2819
|
+
rawAssetBaseUrl: Text$3,
|
|
2820
|
+
verifiedAssetBaseUrl: Text$3,
|
|
2821
|
+
pluginEntries: _Array_(Tuple([Text$3, Text$3])),
|
|
2822
|
+
assetPaths: Strings$1,
|
|
2823
|
+
stylePaths: Strings$1,
|
|
2824
|
+
channels: Strings$1
|
|
2825
|
+
});
|
|
2826
|
+
const NativeCompositionSchema = _Object_({
|
|
2827
|
+
id: Text$3,
|
|
2828
|
+
scope: Union([
|
|
2829
|
+
Literal("global"),
|
|
2830
|
+
Literal("workspace"),
|
|
2831
|
+
Literal("session")
|
|
2832
|
+
]),
|
|
2833
|
+
revision: NumberValue$2,
|
|
2834
|
+
manifestUrl: Text$3,
|
|
2835
|
+
rawAssetBaseUrl: Text$3,
|
|
2836
|
+
pluginEntries: _Array_(Tuple([Text$3, Text$3])),
|
|
2837
|
+
uiEntry: Optional$2(Text$3),
|
|
2838
|
+
channels: Strings$1,
|
|
2839
|
+
plugins: Strings$1
|
|
2840
|
+
});
|
|
2841
|
+
/** A configured template id and the mount whose compositions offer it. */
|
|
2842
|
+
const TemplateDecisionSchema = _Object_({
|
|
2843
|
+
id: Optional$2(Text$3),
|
|
2844
|
+
mount: Union([_Object_({ scope: Literal("global") }), _Object_({
|
|
2845
|
+
scope: Literal("workspace"),
|
|
2846
|
+
workspaceId: Text$3
|
|
2847
|
+
})])
|
|
2848
|
+
});
|
|
2849
|
+
const SessionSummarySchema = _Object_({
|
|
2850
|
+
id: Text$3,
|
|
2851
|
+
workspaceId: Optional$2(Text$3),
|
|
2852
|
+
webComposition: Optional$2(WebCompositionSchema),
|
|
2853
|
+
nativeComposition: Optional$2(NativeCompositionSchema),
|
|
2854
|
+
name: Text$3,
|
|
2855
|
+
cwd: Text$3,
|
|
2856
|
+
createdAt: Text$3,
|
|
2857
|
+
updatedAt: Text$3,
|
|
2858
|
+
phase: Union([
|
|
2859
|
+
Literal("idle"),
|
|
2860
|
+
Literal("turn"),
|
|
2861
|
+
Literal("compaction"),
|
|
2862
|
+
Literal("retry")
|
|
2863
|
+
]),
|
|
2864
|
+
phaseSince: Text$3,
|
|
2865
|
+
attach: Literal("attached"),
|
|
2866
|
+
pendingMessageCount: NumberValue$2,
|
|
2867
|
+
everPrompted: Flag$2,
|
|
2868
|
+
awaitingInput: Flag$2,
|
|
2869
|
+
lastSettledAt: Optional$2(Text$3),
|
|
2870
|
+
git: Optional$2(_Object_({
|
|
2871
|
+
branch: Text$3,
|
|
2872
|
+
dirty: Flag$2
|
|
2873
|
+
})),
|
|
2874
|
+
profile: Optional$2(_Object_({
|
|
2875
|
+
name: Text$3,
|
|
2876
|
+
displayName: Optional$2(Text$3),
|
|
2877
|
+
iconVersion: Optional$2(Text$3)
|
|
2878
|
+
})),
|
|
2879
|
+
parentSessionId: Optional$2(Text$3),
|
|
2880
|
+
sessionProvenance: Optional$2(Text$3),
|
|
2881
|
+
interaction: Optional$2(Union([Literal("interactive"), Literal("unattended")])),
|
|
2882
|
+
/** The line the session's extension published about background work it runs. */
|
|
2883
|
+
activity: Optional$2(_Object_({
|
|
2884
|
+
label: Text$3,
|
|
2885
|
+
attention: Optional$2(Flag$2),
|
|
2886
|
+
since: Optional$2(Text$3)
|
|
2887
|
+
})),
|
|
2888
|
+
/** Tool calls waiting for the person's approval. */
|
|
2889
|
+
pendingApprovalCount: Optional$2(Integer({ minimum: 1 })),
|
|
2890
|
+
pendingSetups: Optional$2(_Array_(_Object_({
|
|
2891
|
+
id: Text$3,
|
|
2892
|
+
name: Text$3,
|
|
2893
|
+
createdAt: Text$3,
|
|
2894
|
+
cwd: Optional$2(Text$3),
|
|
2895
|
+
setupKind: Optional$2(Union([Literal("managed-worktree"), Literal("existing-directory")])),
|
|
2896
|
+
status: Optional$2(Union([
|
|
2897
|
+
Literal("provisioning"),
|
|
2898
|
+
Literal("failed"),
|
|
2899
|
+
Literal("interrupted")
|
|
2900
|
+
])),
|
|
2901
|
+
errorCode: Optional$2(Union([Literal("SESSION_WORKTREE_PROVISION_FAILED"), Literal("SESSION_UNAVAILABLE")]))
|
|
2902
|
+
}))),
|
|
2903
|
+
groups: Optional$2(Strings$1),
|
|
2904
|
+
backgroundWorkActive: Optional$2(Flag$2),
|
|
2905
|
+
/** Present and true for a recorded session the server has not reopened yet. */
|
|
2906
|
+
dormant: Optional$2(Flag$2)
|
|
2907
|
+
});
|
|
2908
|
+
const WorkspaceSchema = _Object_({
|
|
2909
|
+
kind: Optional$2(Literal("session")),
|
|
2910
|
+
instructions: Optional$2(Text$3),
|
|
2911
|
+
id: Text$3,
|
|
2912
|
+
root: Text$3,
|
|
2913
|
+
name: Optional$2(Text$3),
|
|
2914
|
+
available: Optional$2(Flag$2),
|
|
2915
|
+
sandbox: Optional$2(Text$3),
|
|
2916
|
+
/**
|
|
2917
|
+
* The sandbox's state, live: `starting` while it starts or sessions move in, `running` once the host is linked,
|
|
2918
|
+
* `stopping` while it is switched off, `failed` when a start or a switch failed, `unavailable` when its provider
|
|
2919
|
+
* cannot run it. On a workspace without `sandbox`, `unavailable` means the sandbox provider cannot run it now, so
|
|
2920
|
+
* it cannot be switched on; absent means nothing stands in the way.
|
|
2921
|
+
*/
|
|
2922
|
+
sandboxState: Optional$2(Union([
|
|
2923
|
+
Literal("starting"),
|
|
2924
|
+
Literal("running"),
|
|
2925
|
+
Literal("stopping"),
|
|
2926
|
+
Literal("unavailable"),
|
|
2927
|
+
Literal("failed")
|
|
2928
|
+
])),
|
|
2929
|
+
/** A plain sentence for `failed` or `unavailable`, such as 'Docker is not running.'. */
|
|
2930
|
+
sandboxReason: Optional$2(Text$3)
|
|
2931
|
+
});
|
|
2932
|
+
const SavedSession = _Object_({
|
|
2933
|
+
id: Text$3,
|
|
2934
|
+
name: Optional$2(Text$3),
|
|
2935
|
+
firstMessage: Text$3,
|
|
2936
|
+
createdAt: Text$3,
|
|
2937
|
+
updatedAt: Text$3
|
|
2938
|
+
});
|
|
2939
|
+
const query = (name, schema = Text$3, required = false) => ({
|
|
2940
|
+
name,
|
|
2941
|
+
in: "query",
|
|
2942
|
+
required,
|
|
2943
|
+
schema
|
|
2944
|
+
});
|
|
2945
|
+
const body = (schema) => ({
|
|
2946
|
+
contentType: "application/json",
|
|
2947
|
+
required: true,
|
|
2948
|
+
schema
|
|
2949
|
+
});
|
|
2950
|
+
const host = (id, path, method, result, extra = {}) => ({
|
|
2951
|
+
id,
|
|
2952
|
+
path,
|
|
2953
|
+
method,
|
|
2954
|
+
scope: "global",
|
|
2955
|
+
authentication: "owner",
|
|
2956
|
+
description: id,
|
|
2957
|
+
responses: jsonApiResponses(result),
|
|
2958
|
+
...extra
|
|
2959
|
+
});
|
|
2960
|
+
const Principal = _Object_({
|
|
2961
|
+
issuer: Text$3,
|
|
2962
|
+
subject: Text$3
|
|
2963
|
+
});
|
|
2964
|
+
const ProviderGrant = _Object_({
|
|
2965
|
+
tag: Literal("po/grant/v1"),
|
|
2966
|
+
signature: Text$3,
|
|
2967
|
+
payload: _Object_({
|
|
2968
|
+
issuer: Text$3,
|
|
2969
|
+
subject: Text$3,
|
|
2970
|
+
grantId: Text$3,
|
|
2971
|
+
deviceKeyId: Text$3,
|
|
2972
|
+
networkId: Text$3,
|
|
2973
|
+
workspaceId: Text$3,
|
|
2974
|
+
callingHostId: Text$3,
|
|
2975
|
+
targetHostId: Text$3,
|
|
2976
|
+
operations: Strings$1,
|
|
2977
|
+
constraints: Record(Text$3, Union([
|
|
2978
|
+
Text$3,
|
|
2979
|
+
NumberValue$2,
|
|
2980
|
+
Flag$2,
|
|
2981
|
+
Null()
|
|
2982
|
+
])),
|
|
2983
|
+
issuedAt: NumberValue$2,
|
|
2984
|
+
notBefore: NumberValue$2,
|
|
2985
|
+
expiresAt: NumberValue$2,
|
|
2986
|
+
redelegable: Literal(false),
|
|
2987
|
+
revocationEpoch: Optional$2(NumberValue$2)
|
|
2988
|
+
})
|
|
2989
|
+
});
|
|
2990
|
+
const ProviderConsent = _Object_({
|
|
2991
|
+
workspaceId: Text$3,
|
|
2992
|
+
providerHostId: Text$3,
|
|
2993
|
+
packageName: Text$3,
|
|
2994
|
+
owner: Principal,
|
|
2995
|
+
grants: _Array_(ProviderGrant, {
|
|
2996
|
+
minItems: 2,
|
|
2997
|
+
maxItems: 2
|
|
2998
|
+
}),
|
|
2999
|
+
createdAt: NumberValue$2,
|
|
3000
|
+
expiresAt: NumberValue$2
|
|
3001
|
+
});
|
|
3002
|
+
const ConsentCandidate = _Object_({
|
|
3003
|
+
hostId: Text$3,
|
|
3004
|
+
packageName: Text$3,
|
|
3005
|
+
version: Text$3,
|
|
3006
|
+
operations: Strings$1,
|
|
3007
|
+
manifestExpiresAt: NumberValue$2
|
|
3008
|
+
});
|
|
3009
|
+
const ConsentWorkspaceParameter = {
|
|
3010
|
+
name: "workspaceId",
|
|
3011
|
+
in: "path",
|
|
3012
|
+
required: true,
|
|
3013
|
+
schema: Text$3
|
|
3014
|
+
};
|
|
3015
|
+
const Binary = String$1({ contentEncoding: "binary" });
|
|
3016
|
+
const headlessHttpContracts = [
|
|
3017
|
+
host("health", "/api/health", "GET", _Object_({
|
|
3018
|
+
ok: Literal(true),
|
|
3019
|
+
role: Literal("hub"),
|
|
3020
|
+
protocol: Literal(1),
|
|
3021
|
+
sessions: NumberValue$2
|
|
3022
|
+
}), { authentication: "none" }),
|
|
3023
|
+
host("telemetry.browser", "/api/telemetry/browser", "POST", ApiOkSchema, { body: body(_Object_({
|
|
3024
|
+
v: Literal(1),
|
|
3025
|
+
events: _Array_(_Object_({
|
|
3026
|
+
name: String$1({ pattern: "^web\\.browser\\.[a-z_]{1,40}$" }),
|
|
3027
|
+
duration_ms: Optional$2(NumberValue$2),
|
|
3028
|
+
count: Optional$2(NumberValue$2),
|
|
3029
|
+
level: Optional$2(Literal("warn")),
|
|
3030
|
+
attributes: Optional$2(Record(String$1({ pattern: "^[a-z_]{1,32}$" }), Union([String$1({ maxLength: 256 }), NumberValue$2]), { maxProperties: 12 }))
|
|
3031
|
+
}), { maxItems: 10 })
|
|
3032
|
+
})) }),
|
|
3033
|
+
host("compositions", "/api/compositions", "GET", _Object_({
|
|
3034
|
+
network: Optional$2(_Object_({
|
|
3035
|
+
hostId: Text$3,
|
|
3036
|
+
networkId: Text$3,
|
|
3037
|
+
enrollmentGeneration: Optional$2(NumberValue$2)
|
|
3038
|
+
})),
|
|
3039
|
+
/** The computer's own name, which phones show instead of a tunnel address. */
|
|
3040
|
+
displayName: Optional$2(Text$3),
|
|
3041
|
+
global: Optional$2(WebCompositionSchema),
|
|
3042
|
+
nativeGlobal: Optional$2(NativeCompositionSchema),
|
|
3043
|
+
publicKey: Optional$2(Text$3),
|
|
3044
|
+
shell: Optional$2(_Object_({
|
|
3045
|
+
publicKey: Text$3,
|
|
3046
|
+
revision: NumberValue$2
|
|
3047
|
+
})),
|
|
3048
|
+
template: Optional$2(TemplateDecisionSchema),
|
|
3049
|
+
/** The phone app's `native.template` choice, resolved the same way. */
|
|
3050
|
+
nativeTemplate: Optional$2(TemplateDecisionSchema),
|
|
3051
|
+
workspaces: _Array_(_Object_({
|
|
3052
|
+
id: Text$3,
|
|
3053
|
+
root: Text$3,
|
|
3054
|
+
/** `null` for a sandboxed workspace: its plugins run in its sandbox, the host has none for it. */
|
|
3055
|
+
webComposition: Optional$2(Union([WebCompositionSchema, Null()])),
|
|
3056
|
+
nativeComposition: Optional$2(Union([NativeCompositionSchema, Null()])),
|
|
3057
|
+
providers: Optional$2(_Array_(_Object_({
|
|
3058
|
+
hostId: Text$3,
|
|
3059
|
+
packageName: Text$3,
|
|
3060
|
+
version: Text$3,
|
|
3061
|
+
operations: _Array_(_Object_({
|
|
3062
|
+
scope: Union([
|
|
3063
|
+
Literal("global"),
|
|
3064
|
+
Literal("workspace"),
|
|
3065
|
+
Literal("session")
|
|
3066
|
+
]),
|
|
3067
|
+
names: Strings$1
|
|
3068
|
+
})),
|
|
3069
|
+
provenance: Union([
|
|
3070
|
+
Literal("local"),
|
|
3071
|
+
Literal("own"),
|
|
3072
|
+
Literal("consented")
|
|
3073
|
+
]),
|
|
3074
|
+
status: Union([Literal("available"), Literal("unavailable")]),
|
|
3075
|
+
reason: Optional$2(Union([
|
|
3076
|
+
Literal("manifest-missing"),
|
|
3077
|
+
Literal("manifest-expired"),
|
|
3078
|
+
Literal("roster-stale"),
|
|
3079
|
+
Literal("host-removed"),
|
|
3080
|
+
Literal("consent-expired")
|
|
3081
|
+
])),
|
|
3082
|
+
expiresAt: Optional$2(NumberValue$2)
|
|
3083
|
+
})))
|
|
3084
|
+
}))
|
|
3085
|
+
})),
|
|
3086
|
+
host("network.voters.propose", "/api/network/voters", "POST", Json$3, { body: body(_Object_({
|
|
3087
|
+
change: Union([_Object_({
|
|
3088
|
+
network: Text$3,
|
|
3089
|
+
epoch: NumberValue$2,
|
|
3090
|
+
kind: Literal("add"),
|
|
3091
|
+
added: Text$3,
|
|
3092
|
+
addedKey: Text$3
|
|
3093
|
+
}), _Object_({
|
|
3094
|
+
network: Text$3,
|
|
3095
|
+
epoch: NumberValue$2,
|
|
3096
|
+
kind: Literal("evict"),
|
|
3097
|
+
removed: Text$3
|
|
3098
|
+
})]),
|
|
3099
|
+
authorization: Text$3
|
|
3100
|
+
})) }),
|
|
3101
|
+
host("network.consents.list", "/api/network/workspaces/{workspaceId}/consents", "GET", _Object_({
|
|
3102
|
+
consents: _Array_(ProviderConsent),
|
|
3103
|
+
candidates: _Array_(ConsentCandidate)
|
|
3104
|
+
}), { parameters: [ConsentWorkspaceParameter] }),
|
|
3105
|
+
host("network.consents.approve", "/api/network/workspaces/{workspaceId}/consents", "POST", ProviderConsent, {
|
|
3106
|
+
parameters: [ConsentWorkspaceParameter],
|
|
3107
|
+
body: body(_Object_({
|
|
3108
|
+
providerHostId: Text$3,
|
|
3109
|
+
packageName: Text$3,
|
|
3110
|
+
grants: _Array_(ProviderGrant, {
|
|
3111
|
+
minItems: 2,
|
|
3112
|
+
maxItems: 2
|
|
3113
|
+
})
|
|
3114
|
+
})),
|
|
3115
|
+
responses: jsonApiResponses(ProviderConsent, 201)
|
|
3116
|
+
}),
|
|
3117
|
+
host("network.consents.revoke", "/api/network/workspaces/{workspaceId}/consents/{providerHostId}/{packageName}", "DELETE", Null(), {
|
|
3118
|
+
parameters: [
|
|
3119
|
+
ConsentWorkspaceParameter,
|
|
3120
|
+
{
|
|
3121
|
+
name: "providerHostId",
|
|
3122
|
+
in: "path",
|
|
3123
|
+
required: true,
|
|
3124
|
+
schema: Text$3
|
|
3125
|
+
},
|
|
3126
|
+
{
|
|
3127
|
+
name: "packageName",
|
|
3128
|
+
in: "path",
|
|
3129
|
+
required: true,
|
|
3130
|
+
schema: Text$3
|
|
3131
|
+
}
|
|
3132
|
+
],
|
|
3133
|
+
responses: { "204": { description: "Provider consent revoked" } }
|
|
3134
|
+
}),
|
|
3135
|
+
host("directories", "/api/directories", "GET", _Object_({ directories: Strings$1 }), { parameters: [query("q")] }),
|
|
3136
|
+
host("directories.children", "/api/directories/children", "GET", _Object_({
|
|
3137
|
+
path: Text$3,
|
|
3138
|
+
parent: Optional$2(Text$3),
|
|
3139
|
+
directories: Strings$1
|
|
3140
|
+
}), { parameters: [query("path")] }),
|
|
3141
|
+
host("directories.workspaces", "/api/directories/workspaces", "GET", _Object_({
|
|
3142
|
+
root: Text$3,
|
|
3143
|
+
declarations: _Array_(_Object_({
|
|
3144
|
+
name: Text$3,
|
|
3145
|
+
instructions: Optional$2(Text$3),
|
|
3146
|
+
workspaceId: Optional$2(Text$3)
|
|
3147
|
+
}))
|
|
3148
|
+
}), {
|
|
3149
|
+
parameters: [query("path")],
|
|
3150
|
+
availability: "Host provides declaredWorkspaces"
|
|
3151
|
+
}),
|
|
3152
|
+
host("directories.po", "/api/directories/po", "GET", _Object_({ directories: Strings$1 })),
|
|
3153
|
+
host("sessions.list", "/api/workspaces/{workspaceId}/sessions", "GET", _Object_({ sessions: _Array_(SessionSummarySchema) })),
|
|
3154
|
+
host("sessions.create", "/api/workspaces/{workspaceId}/sessions", "POST", _Object_({ sessionId: Text$3 }), {
|
|
3155
|
+
body: body(_Object_({ name: Optional$2(Text$3) })),
|
|
3156
|
+
responses: jsonApiResponses(_Object_({ sessionId: Text$3 }), 201)
|
|
3157
|
+
}),
|
|
3158
|
+
host("sessions.createGeneral", "/api/sessions", "POST", _Object_({
|
|
3159
|
+
sessionId: Text$3,
|
|
3160
|
+
workspace: Optional$2(WorkspaceSchema),
|
|
3161
|
+
session: Optional$2(SessionSummarySchema)
|
|
3162
|
+
}), {
|
|
3163
|
+
body: body(_Object_({
|
|
3164
|
+
name: Optional$2(Text$3),
|
|
3165
|
+
cwd: Optional$2(String$1({ minLength: 1 }))
|
|
3166
|
+
})),
|
|
3167
|
+
availability: "Host provides createGeneralSession when cwd is omitted; explicit cwd remains supported for compatibility",
|
|
3168
|
+
responses: jsonApiResponses(_Object_({
|
|
3169
|
+
sessionId: Text$3,
|
|
3170
|
+
workspace: Optional$2(WorkspaceSchema),
|
|
3171
|
+
session: Optional$2(SessionSummarySchema)
|
|
3172
|
+
}), 201)
|
|
3173
|
+
}),
|
|
3174
|
+
host("sessions.get", "/api/workspaces/{workspaceId}/sessions/{sessionId}", "GET", SessionSummarySchema),
|
|
3175
|
+
host("sessions.delete", "/api/workspaces/{workspaceId}/sessions/{sessionId}", "DELETE", ApiOkSchema),
|
|
3176
|
+
host("sessions.history", "/api/workspaces/{workspaceId}/sessions/{sessionId}/history", "GET", _Object_({ sessions: _Array_(SavedSession) }), { availability: "Host provides sessionHistory" }),
|
|
3177
|
+
host("sessions.restart", "/api/workspaces/{workspaceId}/sessions/{sessionId}/restart", "POST", ApiOkSchema, { availability: "Host provides restartSession" }),
|
|
3178
|
+
host("sessions.revive", "/api/workspaces/{workspaceId}/sessions/{sessionId}/revive", "POST", ApiOkSchema, { availability: "Host provides reviveSession" }),
|
|
3179
|
+
host("sessions.resume", "/api/workspaces/{workspaceId}/sessions/{sessionId}/resume", "POST", _Object_({ sessionId: Text$3 }), {
|
|
3180
|
+
availability: "Host provides resumeSession",
|
|
3181
|
+
body: body(_Object_({ targetSessionId: String$1({ pattern: "^[A-Za-z0-9_-]+$" }) }))
|
|
3182
|
+
}),
|
|
3183
|
+
host("sessions.file", "/api/workspaces/{workspaceId}/sessions/{sessionId}/file", "GET", Binary, {
|
|
3184
|
+
parameters: [query("path", Text$3, true)],
|
|
3185
|
+
responses: {
|
|
3186
|
+
...jsonApiResponses(Binary),
|
|
3187
|
+
"200": {
|
|
3188
|
+
description: "File bytes, MIME type follows the file extension",
|
|
3189
|
+
contentType: "*/*",
|
|
3190
|
+
schema: Binary
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
}),
|
|
3194
|
+
host("workspaces.list", "/api/workspaces", "GET", _Object_({ workspaces: _Array_(WorkspaceSchema) })),
|
|
3195
|
+
host("workspaces.admit", "/api/workspaces", "POST", _Object_({ workspace: WorkspaceSchema }), {
|
|
3196
|
+
body: body(_Object_({
|
|
3197
|
+
root: Optional$2(Text$3),
|
|
3198
|
+
name: Optional$2(Text$3),
|
|
3199
|
+
declaration: Optional$2(Text$3),
|
|
3200
|
+
instructions: Optional$2(Text$3)
|
|
3201
|
+
})),
|
|
3202
|
+
responses: jsonApiResponses(_Object_({ workspace: WorkspaceSchema }), 201)
|
|
3203
|
+
}),
|
|
3204
|
+
host("workspaces.get", "/api/workspaces/{workspaceId}", "GET", _Object_({ workspace: WorkspaceSchema })),
|
|
3205
|
+
host("workspaces.history", "/api/workspaces/{workspaceId}/history", "GET", _Object_({ sessions: _Array_(SavedSession) }), { availability: "Host provides workspaceHistory" }),
|
|
3206
|
+
host("workspaces.resume", "/api/workspaces/{workspaceId}/resume", "POST", _Object_({ sessionId: Text$3 }), {
|
|
3207
|
+
availability: "Host provides resumeWorkspaceSession",
|
|
3208
|
+
body: body(_Object_({ targetSessionId: String$1({ pattern: "^[A-Za-z0-9_-]+$" }) }))
|
|
3209
|
+
}),
|
|
3210
|
+
host("workspaces.removed", "/api/workspaces/{workspaceId}/removed", "GET", _Object_({ sessions: _Array_(Intersect([SavedSession, _Object_({
|
|
3211
|
+
removedAt: Text$3,
|
|
3212
|
+
purgeAt: Text$3
|
|
3213
|
+
})])) }), { availability: "Host provides removedSessions" }),
|
|
3214
|
+
host("workspaces.restoreRemoved", "/api/workspaces/{workspaceId}/removed/{sessionId}/restore", "POST", ApiOkSchema, { availability: "Host provides restoreRemovedSession" }),
|
|
3215
|
+
host("workspaces.setSandbox", "/api/workspaces/{workspaceId}", "PATCH", _Object_({ workspace: WorkspaceSchema }), {
|
|
3216
|
+
availability: "Host provides setWorkspaceSandbox or setWorkspaceInstructions",
|
|
3217
|
+
body: body(Union([_Object_({ sandbox: Union([Text$3, Null()]) }, { additionalProperties: false }), _Object_({ instructions: Text$3 }, { additionalProperties: false })]))
|
|
3218
|
+
}),
|
|
3219
|
+
host("workspaces.remove", "/api/workspaces/{workspaceId}", "DELETE", ApiOkSchema)
|
|
3220
|
+
];
|
|
3221
|
+
const AuthType = Union([Literal("api_key"), Literal("oauth")]);
|
|
3222
|
+
const Provider = _Object_({
|
|
3223
|
+
id: Text$3,
|
|
3224
|
+
name: Text$3,
|
|
3225
|
+
methods: _Array_(_Object_({
|
|
3226
|
+
type: AuthType,
|
|
3227
|
+
label: Text$3
|
|
3228
|
+
})),
|
|
3229
|
+
authenticated: Optional$2(_Object_({
|
|
3230
|
+
type: AuthType,
|
|
3231
|
+
source: Optional$2(Text$3)
|
|
3232
|
+
}))
|
|
3233
|
+
});
|
|
3234
|
+
const LoginEvent = Union([
|
|
3235
|
+
_Object_({
|
|
3236
|
+
type: Literal("info"),
|
|
3237
|
+
message: Text$3,
|
|
3238
|
+
links: Optional$2(_Array_(_Object_({
|
|
3239
|
+
url: Text$3,
|
|
3240
|
+
label: Optional$2(Text$3)
|
|
3241
|
+
})))
|
|
3242
|
+
}),
|
|
3243
|
+
_Object_({
|
|
3244
|
+
type: Literal("auth_url"),
|
|
3245
|
+
url: Text$3,
|
|
3246
|
+
instructions: Optional$2(Text$3)
|
|
3247
|
+
}),
|
|
3248
|
+
_Object_({
|
|
3249
|
+
type: Literal("device_code"),
|
|
3250
|
+
userCode: Text$3,
|
|
3251
|
+
verificationUri: Text$3,
|
|
3252
|
+
intervalSeconds: Optional$2(NumberValue$2),
|
|
3253
|
+
expiresInSeconds: Optional$2(NumberValue$2)
|
|
3254
|
+
}),
|
|
3255
|
+
_Object_({
|
|
3256
|
+
type: Literal("progress"),
|
|
3257
|
+
message: Text$3
|
|
3258
|
+
})
|
|
3259
|
+
]);
|
|
3260
|
+
const LoginFlowSchema = _Object_({
|
|
3261
|
+
id: Text$3,
|
|
3262
|
+
providerId: Text$3,
|
|
3263
|
+
providerName: Text$3,
|
|
3264
|
+
type: AuthType,
|
|
3265
|
+
status: Union([
|
|
3266
|
+
Literal("running"),
|
|
3267
|
+
Literal("succeeded"),
|
|
3268
|
+
Literal("failed"),
|
|
3269
|
+
Literal("cancelled")
|
|
3270
|
+
]),
|
|
3271
|
+
events: _Array_(LoginEvent),
|
|
3272
|
+
prompt: Optional$2(_Object_({
|
|
3273
|
+
id: Text$3,
|
|
3274
|
+
type: Union([
|
|
3275
|
+
Literal("text"),
|
|
3276
|
+
Literal("secret"),
|
|
3277
|
+
Literal("select"),
|
|
3278
|
+
Literal("manual_code")
|
|
3279
|
+
]),
|
|
3280
|
+
message: Text$3,
|
|
3281
|
+
placeholder: Optional$2(Text$3),
|
|
3282
|
+
options: Optional$2(_Array_(_Object_({
|
|
3283
|
+
id: Text$3,
|
|
3284
|
+
label: Text$3,
|
|
3285
|
+
description: Optional$2(Text$3)
|
|
3286
|
+
})))
|
|
3287
|
+
})),
|
|
3288
|
+
remote: Optional$2(Flag$2),
|
|
3289
|
+
error: Optional$2(Text$3)
|
|
3290
|
+
});
|
|
3291
|
+
const Flow = _Object_({ flow: LoginFlowSchema });
|
|
3292
|
+
const machineHttpContracts = [
|
|
3293
|
+
host("providers.list", "/providers", "GET", _Object_({ providers: _Array_(Provider) })),
|
|
3294
|
+
host("models.list", "/models", "GET", _Object_({ models: _Array_(_Object_({
|
|
3295
|
+
value: Text$3,
|
|
3296
|
+
label: Text$3,
|
|
3297
|
+
group: Text$3
|
|
3298
|
+
})) })),
|
|
3299
|
+
host("providers.logout", "/providers/{providerId}", "DELETE", ApiOkSchema),
|
|
3300
|
+
host("logins.create", "/logins", "POST", Flow, {
|
|
3301
|
+
body: body(_Object_({
|
|
3302
|
+
providerId: Text$3,
|
|
3303
|
+
type: AuthType
|
|
3304
|
+
})),
|
|
3305
|
+
responses: jsonApiResponses(Flow, 201)
|
|
3306
|
+
}),
|
|
3307
|
+
host("logins.get", "/logins/{flowId}", "GET", Flow),
|
|
3308
|
+
host("logins.cancel", "/logins/{flowId}", "DELETE", Flow),
|
|
3309
|
+
host("logins.answer", "/logins/{flowId}/answer", "POST", Flow, { body: body(_Object_({
|
|
3310
|
+
promptId: Text$3,
|
|
3311
|
+
value: Text$3
|
|
3312
|
+
})) })
|
|
3313
|
+
].map((route) => ({
|
|
3314
|
+
...route,
|
|
3315
|
+
basePath: "po"
|
|
3316
|
+
}));
|
|
3317
|
+
const Source = Union([
|
|
3318
|
+
Literal("extension"),
|
|
3319
|
+
Literal("mcp"),
|
|
3320
|
+
Literal("plugin"),
|
|
3321
|
+
Literal("core")
|
|
3322
|
+
]);
|
|
3323
|
+
const Detail = Union([
|
|
3324
|
+
_Object_({
|
|
3325
|
+
itemKind: Literal("tool"),
|
|
3326
|
+
name: Text$3,
|
|
3327
|
+
owner: Text$3,
|
|
3328
|
+
source: Source,
|
|
3329
|
+
active: Flag$2,
|
|
3330
|
+
tokens: _Object_({
|
|
3331
|
+
schemaTokens: NumberValue$2,
|
|
3332
|
+
promptTokens: NumberValue$2,
|
|
3333
|
+
totalTokens: NumberValue$2
|
|
3334
|
+
}),
|
|
3335
|
+
description: Optional$2(Text$3),
|
|
3336
|
+
promptSnippet: Optional$2(Text$3),
|
|
3337
|
+
promptGuidelines: Optional$2(Strings$1),
|
|
3338
|
+
parameters: Optional$2(Json$3)
|
|
3339
|
+
}),
|
|
3340
|
+
_Object_({
|
|
3341
|
+
itemKind: Literal("skill"),
|
|
3342
|
+
name: Text$3,
|
|
3343
|
+
owner: Text$3,
|
|
3344
|
+
source: Source,
|
|
3345
|
+
active: Literal(true),
|
|
3346
|
+
tokens: NumberValue$2,
|
|
3347
|
+
description: Text$3,
|
|
3348
|
+
filePath: Optional$2(Text$3),
|
|
3349
|
+
modelInvocable: Flag$2
|
|
3350
|
+
}),
|
|
3351
|
+
_Object_({
|
|
3352
|
+
itemKind: Literal("prompt"),
|
|
3353
|
+
name: Literal("system"),
|
|
3354
|
+
tokens: NumberValue$2,
|
|
3355
|
+
stage: Union([Literal("base"), Literal("effective")]),
|
|
3356
|
+
text: Text$3
|
|
3357
|
+
})
|
|
3358
|
+
]);
|
|
3359
|
+
const sessionHttpContracts = [
|
|
3360
|
+
{
|
|
3361
|
+
...host("context.current", CURRENT_ROUTE, "GET", _Object_({
|
|
3362
|
+
version: Literal(1),
|
|
3363
|
+
revision: NumberValue$2,
|
|
3364
|
+
selection: _Object_({
|
|
3365
|
+
majorMode: Text$3,
|
|
3366
|
+
domains: Strings$1,
|
|
3367
|
+
profile: Optional$2(Text$3)
|
|
3368
|
+
}),
|
|
3369
|
+
groups: _Array_(_Object_({
|
|
3370
|
+
id: Text$3,
|
|
3371
|
+
label: Text$3,
|
|
3372
|
+
kind: Union([
|
|
3373
|
+
Literal("major"),
|
|
3374
|
+
Literal("minor"),
|
|
3375
|
+
Literal("domain"),
|
|
3376
|
+
Literal("shared"),
|
|
3377
|
+
Literal("core")
|
|
3378
|
+
]),
|
|
3379
|
+
items: _Array_(_Object_({
|
|
3380
|
+
name: Text$3,
|
|
3381
|
+
itemKind: Union([Literal("tool"), Literal("skill")]),
|
|
3382
|
+
source: Source,
|
|
3383
|
+
owner: Text$3,
|
|
3384
|
+
tokens: NumberValue$2,
|
|
3385
|
+
active: Flag$2
|
|
3386
|
+
})),
|
|
3387
|
+
tokens: NumberValue$2,
|
|
3388
|
+
inactiveTokens: NumberValue$2
|
|
3389
|
+
})),
|
|
3390
|
+
totalTokens: NumberValue$2,
|
|
3391
|
+
inactiveTokens: NumberValue$2,
|
|
3392
|
+
systemPrompt: Optional$2(_Object_({
|
|
3393
|
+
tokens: NumberValue$2,
|
|
3394
|
+
stage: Union([Literal("base"), Literal("effective")])
|
|
3395
|
+
})),
|
|
3396
|
+
estimator: Literal("gpt-tokenizer")
|
|
3397
|
+
})),
|
|
3398
|
+
scope: "session",
|
|
3399
|
+
basePath: API_BASE_PATH
|
|
3400
|
+
},
|
|
3401
|
+
{
|
|
3402
|
+
...host("context.item", ITEM_ROUTE, "GET", _Object_({
|
|
3403
|
+
revision: NumberValue$2,
|
|
3404
|
+
item: Detail
|
|
3405
|
+
}), { parameters: [query("kind", Union([
|
|
3406
|
+
Literal("tool"),
|
|
3407
|
+
Literal("skill"),
|
|
3408
|
+
Literal("prompt")
|
|
3409
|
+
]), true), query("name", Text$3, true)] }),
|
|
3410
|
+
scope: "session",
|
|
3411
|
+
basePath: API_BASE_PATH
|
|
3412
|
+
},
|
|
3413
|
+
{
|
|
3414
|
+
...host("files.complete", "/", "GET", _Object_({ files: Strings$1 }), { parameters: [query("q", String$1({ maxLength: 256 }))] }),
|
|
3415
|
+
scope: "session",
|
|
3416
|
+
basePath: "files"
|
|
3417
|
+
}
|
|
3418
|
+
];
|
|
3419
|
+
//#endregion
|
|
3420
|
+
//#region ../../core/po-core/src/schemas/protocolHubContract.ts
|
|
3421
|
+
const Text$2 = String$1();
|
|
3422
|
+
const Json$2 = Unsafe({});
|
|
3423
|
+
/** A live session frame every hub client needs (notification entries and agent dialogs) until it is acknowledged. */
|
|
3424
|
+
const HubNoticeSchema = _Object_({
|
|
3425
|
+
id: Text$2,
|
|
3426
|
+
sessionId: Text$2,
|
|
3427
|
+
frame: Record(Text$2, Json$2)
|
|
3428
|
+
});
|
|
3429
|
+
/** Native UI delivery metadata is HTTP-only; adding it must not refuse existing po.hub@1 clients. */
|
|
3430
|
+
const HubSessionSchema = _Object_({
|
|
3431
|
+
...SessionSummarySchema.properties,
|
|
3432
|
+
nativeComposition: Optional$4(Omit(NativeCompositionSchema, ["uiEntry"]))
|
|
3433
|
+
});
|
|
3434
|
+
/** Instructions are HTTP-only so existing po.hub@1 clients keep the same wire contract. */
|
|
3435
|
+
const HubWorkspaceSchema = Omit(WorkspaceSchema, ["instructions"]);
|
|
3436
|
+
/** Per shared mount (`global`, `workspace:<id>`), a counter that rises when its plugin composition changes. */
|
|
3437
|
+
const HubCompositionsSchema = Record(Text$2, Integer({ minimum: 0 }));
|
|
3438
|
+
const HubState = {
|
|
3439
|
+
sessions: Record(Text$2, HubSessionSchema),
|
|
3440
|
+
workspaces: Record(Text$2, HubWorkspaceSchema),
|
|
3441
|
+
pending: _Array_(HubNoticeSchema),
|
|
3442
|
+
compositions: HubCompositionsSchema
|
|
3443
|
+
};
|
|
3444
|
+
const PoHubStateSchema = _Object_(HubState);
|
|
3445
|
+
/** What one connection may see: its sessions, its workspaces, and the notices it has not acknowledged. */
|
|
3446
|
+
const PoHubContract = remote("po.hub", {
|
|
3447
|
+
version: 1,
|
|
3448
|
+
host: hostNamed(PO_SERVER_HOST),
|
|
3449
|
+
input: chordSchema(_Object_({})),
|
|
3450
|
+
variants: { default: {
|
|
3451
|
+
state: chordStates(HubState),
|
|
3452
|
+
methods: chordMethods({
|
|
3453
|
+
readHome: {
|
|
3454
|
+
args: _Object_({
|
|
3455
|
+
offset: Optional$4(Integer({ minimum: 0 })),
|
|
3456
|
+
limit: Optional$4(Integer({ minimum: 1 })),
|
|
3457
|
+
source: Optional$4(Text$2),
|
|
3458
|
+
workspaceId: Optional$4(Text$2)
|
|
3459
|
+
}),
|
|
3460
|
+
result: Unsafe({})
|
|
3461
|
+
},
|
|
3462
|
+
invoke: {
|
|
3463
|
+
args: PoPluginCallSchema,
|
|
3464
|
+
result: Json$2
|
|
3465
|
+
},
|
|
3466
|
+
ackNotice: { args: _Object_({ id: Text$2 }) }
|
|
3467
|
+
})
|
|
3468
|
+
} }
|
|
3469
|
+
});
|
|
3470
|
+
/**
|
|
3471
|
+
* Per topic (`global:<name>`, `workspace:<id>:<name>`), a counter the host raises when that data changes, so a
|
|
3472
|
+
* client fetches it again instead of polling. A separate contract: a host without it leaves clients on
|
|
3473
|
+
* fetch-on-open rather than refusing the whole hub as out of date.
|
|
3474
|
+
*/
|
|
3475
|
+
const HubRevisionsSchema = Record(Text$2, Integer({ minimum: 0 }));
|
|
3476
|
+
const PoHubRevisionsContract = remote("po.hub.revisions", {
|
|
3477
|
+
version: 1,
|
|
3478
|
+
host: hostNamed(PO_SERVER_HOST),
|
|
3479
|
+
input: chordSchema(_Object_({})),
|
|
3480
|
+
variants: { default: {
|
|
3481
|
+
state: chordStates({ revisions: HubRevisionsSchema }),
|
|
3482
|
+
methods: chordMethods({})
|
|
3483
|
+
} }
|
|
3484
|
+
});
|
|
3485
|
+
//#endregion
|
|
3486
|
+
//#region ../../core/po-core/src/schemas/protocolThreadContract.ts
|
|
3487
|
+
/** The thread's latest frame: `transcript_state` while its child runs, `transcript_ready` once it has finished. */
|
|
3488
|
+
const PoThreadFrameSchema = Union([Null(), Intersect([_Object_({ type: String$1() }), Record(String$1(), Unsafe({}))])]);
|
|
3489
|
+
/** One child thread of a session, followed only while someone holds it. */
|
|
3490
|
+
const PoThreadContract = remote("po.thread", {
|
|
3491
|
+
version: 1,
|
|
3492
|
+
host: hostNamed(PO_SERVER_HOST),
|
|
3493
|
+
input: chordSchema(_Object_({
|
|
3494
|
+
sessionId: String$1({ minLength: 1 }),
|
|
3495
|
+
threadId: String$1({ minLength: 1 })
|
|
3496
|
+
})),
|
|
3497
|
+
variants: { default: { state: chordStates({ frame: PoThreadFrameSchema }) } }
|
|
3498
|
+
});
|
|
3499
|
+
//#endregion
|
|
3500
|
+
//#region ../../core/po-core/src/schemas/sessionApiContracts.ts
|
|
3501
|
+
const Text$1 = String$1();
|
|
3502
|
+
const NumberValue$1 = Number$1();
|
|
3503
|
+
const Flag$1 = Boolean();
|
|
3504
|
+
const Json$1 = Unsafe(Unknown({ description: "Strict JSON application value supplied by the active tool, journal entry, or extension; validated by the Pi codec." }));
|
|
3505
|
+
const Optional$1 = Optional$4;
|
|
3506
|
+
const Strings = _Array_(Text$1);
|
|
3507
|
+
const Model = _Object_({
|
|
3508
|
+
provider: Text$1,
|
|
3509
|
+
id: Text$1
|
|
3510
|
+
});
|
|
3511
|
+
const Thinking = Union([
|
|
3512
|
+
Literal("off"),
|
|
3513
|
+
Literal("minimal"),
|
|
3514
|
+
Literal("low"),
|
|
3515
|
+
Literal("medium"),
|
|
3516
|
+
Literal("high"),
|
|
3517
|
+
Literal("max"),
|
|
3518
|
+
Literal("xhigh")
|
|
3519
|
+
]);
|
|
3520
|
+
const Phase = Union([
|
|
3521
|
+
Literal("idle"),
|
|
3522
|
+
Literal("turn"),
|
|
3523
|
+
Literal("compaction"),
|
|
3524
|
+
Literal("retry")
|
|
3525
|
+
]);
|
|
3526
|
+
const Image = _Object_({
|
|
3527
|
+
type: Literal("image"),
|
|
3528
|
+
data: Text$1,
|
|
3529
|
+
mimeType: Text$1
|
|
3530
|
+
});
|
|
3531
|
+
const TextPart = _Object_({
|
|
3532
|
+
type: Literal("text"),
|
|
3533
|
+
text: Text$1
|
|
3534
|
+
});
|
|
3535
|
+
const ThinkingPart = _Object_({
|
|
3536
|
+
type: Literal("thinking"),
|
|
3537
|
+
thinking: Text$1,
|
|
3538
|
+
redacted: Optional$1(Literal(true))
|
|
3539
|
+
});
|
|
3540
|
+
const Content = Union([Image, TextPart]);
|
|
3541
|
+
const Usage = _Object_({
|
|
3542
|
+
input: NumberValue$1,
|
|
3543
|
+
output: NumberValue$1,
|
|
3544
|
+
cacheRead: NumberValue$1,
|
|
3545
|
+
cacheWrite: NumberValue$1,
|
|
3546
|
+
total: NumberValue$1
|
|
3547
|
+
});
|
|
3548
|
+
const Message = _Object_({
|
|
3549
|
+
text: Text$1,
|
|
3550
|
+
images: Optional$1(_Array_(Image))
|
|
3551
|
+
});
|
|
3552
|
+
const Lifecycle = _Object_({
|
|
3553
|
+
revision: NumberValue$1,
|
|
3554
|
+
operation: Union([Null(), _Object_({
|
|
3555
|
+
id: Text$1,
|
|
3556
|
+
kind: Union([
|
|
3557
|
+
Literal("run"),
|
|
3558
|
+
Literal("compaction"),
|
|
3559
|
+
Literal("navigation")
|
|
3560
|
+
]),
|
|
3561
|
+
status: Union([Literal("open"), Literal("aborting")])
|
|
3562
|
+
})]),
|
|
3563
|
+
paused: Flag$1,
|
|
3564
|
+
queue: _Array_(_Object_({
|
|
3565
|
+
id: Text$1,
|
|
3566
|
+
text: Text$1,
|
|
3567
|
+
images: Optional$1(_Array_(Image)),
|
|
3568
|
+
delivery: Union([
|
|
3569
|
+
Literal("steer"),
|
|
3570
|
+
Literal("followUp"),
|
|
3571
|
+
Literal("nextRun")
|
|
3572
|
+
]),
|
|
3573
|
+
scheduling: Union([Literal("automatic"), Literal("held")]),
|
|
3574
|
+
disposition: Union([Literal("pending"), Literal("handoff")])
|
|
3575
|
+
}))
|
|
3576
|
+
});
|
|
3577
|
+
const Frame = Intersect([_Object_({ type: Text$1 }), Record(Text$1, Json$1)], { description: "Discriminated extension presentation frame; selected channel schemas describe package payloads." });
|
|
3578
|
+
const ProtocolEvent = _Object_({
|
|
3579
|
+
sequence: NumberValue$1,
|
|
3580
|
+
frame: Frame
|
|
3581
|
+
});
|
|
3582
|
+
const SessionServiceStateSchema = _Object_({
|
|
3583
|
+
snapshot: _Object_({
|
|
3584
|
+
fastMode: Flag$1,
|
|
3585
|
+
locked: Flag$1,
|
|
3586
|
+
lifecycle: Optional$1(Lifecycle)
|
|
3587
|
+
}),
|
|
3588
|
+
presentation: Optional$1(_Object_({
|
|
3589
|
+
revision: NumberValue$1,
|
|
3590
|
+
dropped: NumberValue$1,
|
|
3591
|
+
resetRevision: Optional$1(NumberValue$1),
|
|
3592
|
+
events: _Array_(ProtocolEvent),
|
|
3593
|
+
projections: _Array_(ProtocolEvent)
|
|
3594
|
+
})),
|
|
3595
|
+
live: Optional$1(_Object_({
|
|
3596
|
+
phase: Phase,
|
|
3597
|
+
message: Optional$1(_Object_({
|
|
3598
|
+
role: Literal("assistant"),
|
|
3599
|
+
content: _Array_(Union([TextPart, ThinkingPart])),
|
|
3600
|
+
model: Text$1,
|
|
3601
|
+
timestamp: NumberValue$1
|
|
3602
|
+
})),
|
|
3603
|
+
tools: Record(Text$1, _Object_({
|
|
3604
|
+
toolCallId: Text$1,
|
|
3605
|
+
toolName: Text$1,
|
|
3606
|
+
args: Json$1,
|
|
3607
|
+
partialResult: Optional$1(_Object_({
|
|
3608
|
+
content: _Array_(Content),
|
|
3609
|
+
details: Optional$1(Json$1)
|
|
3610
|
+
}))
|
|
3611
|
+
}))
|
|
3612
|
+
}))
|
|
3613
|
+
});
|
|
3614
|
+
/** Argument and result schemas of the `po.session` methods; the Chord contract and the API docs both read them. */
|
|
3615
|
+
const SessionMethodSchemas = {
|
|
3616
|
+
readTranscriptPage: {
|
|
3617
|
+
args: _Object_({
|
|
3618
|
+
cursor: Optional$1(Text$1),
|
|
3619
|
+
direction: Optional$1(Union([Literal("older"), Literal("newer")])),
|
|
3620
|
+
limit: Optional$1(NumberValue$1),
|
|
3621
|
+
threadId: Optional$1(Text$1),
|
|
3622
|
+
entryId: Optional$1(Text$1)
|
|
3623
|
+
}),
|
|
3624
|
+
result: _Object_({
|
|
3625
|
+
entries: _Array_(Json$1),
|
|
3626
|
+
startCursor: Union([Text$1, Null()]),
|
|
3627
|
+
endCursor: Union([Text$1, Null()]),
|
|
3628
|
+
olderCursor: Union([Text$1, Null()]),
|
|
3629
|
+
newerCursor: Union([Text$1, Null()]),
|
|
3630
|
+
generation: NumberValue$1,
|
|
3631
|
+
revision: NumberValue$1,
|
|
3632
|
+
context: _Array_(Json$1)
|
|
3633
|
+
})
|
|
3634
|
+
},
|
|
3635
|
+
prompt: { args: Union([Text$1, _Object_({
|
|
3636
|
+
...Message.properties,
|
|
3637
|
+
waitFor: Optional$1(Union([Literal("accepted"), Literal("settled")]))
|
|
3638
|
+
})]) },
|
|
3639
|
+
steer: { args: Union([Text$1, Message]) },
|
|
3640
|
+
abort: {},
|
|
3641
|
+
abortOperation: { args: _Object_({ operationId: Text$1 }) },
|
|
3642
|
+
setModel: { args: Model },
|
|
3643
|
+
setThinking: { args: Thinking },
|
|
3644
|
+
setFastMode: { args: Flag$1 },
|
|
3645
|
+
setAgentLock: { args: Flag$1 },
|
|
3646
|
+
followUp: { args: Message },
|
|
3647
|
+
enqueueAutomatic: {
|
|
3648
|
+
args: Message,
|
|
3649
|
+
result: _Object_({ id: Text$1 })
|
|
3650
|
+
},
|
|
3651
|
+
removeQueued: {
|
|
3652
|
+
args: _Object_({ id: Text$1 }),
|
|
3653
|
+
result: Union([
|
|
3654
|
+
Literal("removed"),
|
|
3655
|
+
Literal("in_flight"),
|
|
3656
|
+
Literal("already_consumed"),
|
|
3657
|
+
Literal("not_found")
|
|
3658
|
+
])
|
|
3659
|
+
},
|
|
3660
|
+
promoteQueued: {
|
|
3661
|
+
args: _Object_({
|
|
3662
|
+
id: Text$1,
|
|
3663
|
+
operationId: Optional$1(Text$1)
|
|
3664
|
+
}),
|
|
3665
|
+
result: Union([
|
|
3666
|
+
Literal("promoted"),
|
|
3667
|
+
Literal("in_flight"),
|
|
3668
|
+
Literal("target_changed"),
|
|
3669
|
+
Literal("not_found")
|
|
3670
|
+
])
|
|
3671
|
+
},
|
|
3672
|
+
resumeQueue: {},
|
|
3673
|
+
clearQueue: { result: _Object_({
|
|
3674
|
+
steering: Strings,
|
|
3675
|
+
followUp: Strings
|
|
3676
|
+
}) },
|
|
3677
|
+
rewind: {
|
|
3678
|
+
args: _Object_({
|
|
3679
|
+
itemId: Text$1,
|
|
3680
|
+
summarize: Optional$1(Flag$1),
|
|
3681
|
+
customInstructions: Optional$1(Text$1),
|
|
3682
|
+
replaceInstructions: Optional$1(Flag$1),
|
|
3683
|
+
label: Optional$1(Text$1)
|
|
3684
|
+
}),
|
|
3685
|
+
result: _Object_({
|
|
3686
|
+
editorText: Optional$1(Text$1),
|
|
3687
|
+
cancelled: Flag$1,
|
|
3688
|
+
aborted: Optional$1(Flag$1),
|
|
3689
|
+
summaryEntry: Optional$1(_Object_({
|
|
3690
|
+
id: Text$1,
|
|
3691
|
+
parentId: Union([Text$1, Null()]),
|
|
3692
|
+
timestamp: Text$1,
|
|
3693
|
+
fromId: Text$1,
|
|
3694
|
+
summary: Text$1,
|
|
3695
|
+
details: Optional$1(Json$1),
|
|
3696
|
+
usage: Optional$1(Usage),
|
|
3697
|
+
fromHook: Optional$1(Flag$1)
|
|
3698
|
+
}))
|
|
3699
|
+
})
|
|
3700
|
+
},
|
|
3701
|
+
extensionUiResponse: { args: Union([
|
|
3702
|
+
_Object_({
|
|
3703
|
+
id: Text$1,
|
|
3704
|
+
value: Text$1
|
|
3705
|
+
}),
|
|
3706
|
+
_Object_({
|
|
3707
|
+
id: Text$1,
|
|
3708
|
+
confirmed: Flag$1
|
|
3709
|
+
}),
|
|
3710
|
+
_Object_({
|
|
3711
|
+
id: Text$1,
|
|
3712
|
+
cancelled: Literal(true)
|
|
3713
|
+
})
|
|
3714
|
+
]) },
|
|
3715
|
+
getState: { result: _Object_({
|
|
3716
|
+
model: Optional$1(Model),
|
|
3717
|
+
thinkingLevel: Thinking,
|
|
3718
|
+
fastMode: Flag$1,
|
|
3719
|
+
agentLocked: Optional$1(Flag$1),
|
|
3720
|
+
isStreaming: Flag$1,
|
|
3721
|
+
isCompacting: Flag$1,
|
|
3722
|
+
steeringMode: Union([Literal("all"), Literal("one-at-a-time")]),
|
|
3723
|
+
followUpMode: Union([Literal("all"), Literal("one-at-a-time")]),
|
|
3724
|
+
sessionId: Text$1,
|
|
3725
|
+
sessionName: Optional$1(Text$1),
|
|
3726
|
+
autoCompactionEnabled: Flag$1,
|
|
3727
|
+
messageCount: NumberValue$1,
|
|
3728
|
+
pendingMessageCount: NumberValue$1,
|
|
3729
|
+
operationId: Optional$1(Text$1),
|
|
3730
|
+
executionStatus: Optional$1(Union([Literal("open"), Literal("aborting")])),
|
|
3731
|
+
queuePaused: Optional$1(Flag$1),
|
|
3732
|
+
queueRevision: Optional$1(NumberValue$1)
|
|
3733
|
+
}) },
|
|
3734
|
+
getSessionStats: { result: _Object_({
|
|
3735
|
+
sessionId: Text$1,
|
|
3736
|
+
totalMessages: NumberValue$1,
|
|
3737
|
+
tokens: Usage,
|
|
3738
|
+
cost: NumberValue$1,
|
|
3739
|
+
contextUsage: Optional$1(_Object_({
|
|
3740
|
+
tokens: Union([NumberValue$1, Null()]),
|
|
3741
|
+
contextWindow: NumberValue$1,
|
|
3742
|
+
percent: Union([NumberValue$1, Null()])
|
|
3743
|
+
}))
|
|
3744
|
+
}) },
|
|
3745
|
+
getCommands: { result: _Array_(_Object_({
|
|
3746
|
+
name: Text$1,
|
|
3747
|
+
description: Optional$1(Text$1),
|
|
3748
|
+
source: Union([
|
|
3749
|
+
Literal("extension"),
|
|
3750
|
+
Literal("prompt"),
|
|
3751
|
+
Literal("skill")
|
|
3752
|
+
]),
|
|
3753
|
+
sourceInfo: Optional$1(_Object_({
|
|
3754
|
+
path: Text$1,
|
|
3755
|
+
source: Text$1,
|
|
3756
|
+
scope: Union([
|
|
3757
|
+
Literal("user"),
|
|
3758
|
+
Literal("project"),
|
|
3759
|
+
Literal("temporary")
|
|
3760
|
+
]),
|
|
3761
|
+
origin: Union([Literal("package"), Literal("top-level")]),
|
|
3762
|
+
baseDir: Optional$1(Text$1)
|
|
3763
|
+
}))
|
|
3764
|
+
})) },
|
|
3765
|
+
getAvailableModels: { result: _Array_(Model) },
|
|
3766
|
+
getAvailableThinkingLevels: { result: _Array_(Thinking) },
|
|
3767
|
+
compact: {
|
|
3768
|
+
args: _Object_({ customInstructions: Optional$1(Text$1) }),
|
|
3769
|
+
result: Json$1
|
|
3770
|
+
},
|
|
3771
|
+
setName: { args: Text$1 },
|
|
3772
|
+
setGroups: { args: _Array_(Text$1) }
|
|
3773
|
+
};
|
|
3774
|
+
/** The `po.session` methods as Chord specs. */
|
|
3775
|
+
const SessionMethods = chordMethods(SessionMethodSchemas);
|
|
3776
|
+
const ErrorSchema = _Object_({
|
|
3777
|
+
code: Text$1,
|
|
3778
|
+
message: Text$1
|
|
3779
|
+
});
|
|
3780
|
+
const documented = (id, service, member, direction, input, description) => ({
|
|
3781
|
+
id,
|
|
3782
|
+
scope: service === "po.hub" ? "global" : "session",
|
|
3783
|
+
service,
|
|
3784
|
+
member,
|
|
3785
|
+
direction,
|
|
3786
|
+
kind: direction === "server-to-client" ? "state" : "method",
|
|
3787
|
+
input,
|
|
3788
|
+
...direction === "server-to-client" ? {} : { errors: ErrorSchema },
|
|
3789
|
+
description
|
|
3790
|
+
});
|
|
3791
|
+
const sessionSocketContracts = [
|
|
3792
|
+
...Object.entries(SessionMethodSchemas).map(([member, { args, result }]) => ({
|
|
3793
|
+
id: `session.${member}`,
|
|
3794
|
+
scope: "session",
|
|
3795
|
+
service: "po.session",
|
|
3796
|
+
member,
|
|
3797
|
+
direction: "client-to-server",
|
|
3798
|
+
kind: "method",
|
|
3799
|
+
description: `Session ${member}. The Chord call carries the argument; a void result is null.`,
|
|
3800
|
+
input: Tuple(args === void 0 ? [] : [args]),
|
|
3801
|
+
...result === void 0 ? {} : { output: result },
|
|
3802
|
+
errors: ErrorSchema
|
|
3803
|
+
})),
|
|
3804
|
+
documented("session.state", "po.session", "state", "server-to-client", SessionServiceStateSchema, "The `state` member of `po.session`, reconstructed from Chord snapshot and delta frames."),
|
|
3805
|
+
documented("hub.state", "po.hub", "state", "server-to-client", PoHubStateSchema, "Sessions and workspaces this connection may see, and notices it has not acknowledged."),
|
|
3806
|
+
documented("thread.frame", "po.thread", "frame", "server-to-client", PoThreadFrameSchema, "The latest frame of one child thread: transcript_state while it runs, transcript_ready once finished."),
|
|
3807
|
+
documented("channels.latest", "po.channels", "latest", "server-to-client", PoChannelsStateSchema, "The latest payload of each extension channel frame type for one session."),
|
|
3808
|
+
documented("channels.receive", "po.channels", "receive", "client-to-server", Tuple([ChannelFrameSchema]), "Send one extension channel frame to the session.")
|
|
3809
|
+
];
|
|
3810
|
+
const Schema = Unsafe(Union([Boolean(), Record(String$1(), Unknown())]));
|
|
3811
|
+
const Scope = Union([
|
|
3812
|
+
Literal("global"),
|
|
3813
|
+
Literal("workspace"),
|
|
3814
|
+
Literal("session")
|
|
3815
|
+
]);
|
|
3816
|
+
const Named = String$1({ minLength: 1 });
|
|
3817
|
+
const ResponseSchema = _Object_({
|
|
3818
|
+
description: Named,
|
|
3819
|
+
contentType: Optional$4(Named),
|
|
3820
|
+
schema: Optional$4(Schema),
|
|
3821
|
+
events: Optional$4(Record(Named, Schema))
|
|
3822
|
+
});
|
|
3823
|
+
_Object_({
|
|
3824
|
+
version: Literal(1),
|
|
3825
|
+
protocols: Optional$4(Record(Named, Named)),
|
|
3826
|
+
schemas: Optional$4(Record(Named, Schema)),
|
|
3827
|
+
http: _Array_(_Object_({
|
|
3828
|
+
id: Named,
|
|
3829
|
+
scope: Scope,
|
|
3830
|
+
/** Omit for host-owned absolute routes. */
|
|
3831
|
+
basePath: Optional$4(String$1({ pattern: "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" })),
|
|
3832
|
+
path: String$1({ pattern: "^/" }),
|
|
3833
|
+
method: Union([
|
|
3834
|
+
Literal("GET"),
|
|
3835
|
+
Literal("POST"),
|
|
3836
|
+
Literal("PUT"),
|
|
3837
|
+
Literal("PATCH"),
|
|
3838
|
+
Literal("DELETE"),
|
|
3839
|
+
Literal("HEAD"),
|
|
3840
|
+
Literal("OPTIONS")
|
|
3841
|
+
]),
|
|
3842
|
+
description: Named,
|
|
3843
|
+
availability: Optional$4(Named),
|
|
3844
|
+
authentication: Union([
|
|
3845
|
+
Literal("none"),
|
|
3846
|
+
Literal("owner"),
|
|
3847
|
+
Literal("device")
|
|
3848
|
+
]),
|
|
3849
|
+
parameters: Optional$4(_Array_(_Object_({
|
|
3850
|
+
name: Named,
|
|
3851
|
+
in: Union([
|
|
3852
|
+
Literal("path"),
|
|
3853
|
+
Literal("query"),
|
|
3854
|
+
Literal("header")
|
|
3855
|
+
]),
|
|
3856
|
+
required: Boolean(),
|
|
3857
|
+
schema: Schema
|
|
3858
|
+
}))),
|
|
3859
|
+
body: Optional$4(_Object_({
|
|
3860
|
+
contentType: Named,
|
|
3861
|
+
contentTypes: Optional$4(_Array_(Named, { minItems: 1 })),
|
|
3862
|
+
required: Boolean(),
|
|
3863
|
+
schema: Schema
|
|
3864
|
+
})),
|
|
3865
|
+
responses: Record(String$1({ pattern: "^(?:[1-5][0-9]{2}|default)$" }), ResponseSchema, { minProperties: 1 })
|
|
3866
|
+
})),
|
|
3867
|
+
sockets: _Array_(_Object_({
|
|
3868
|
+
id: Named,
|
|
3869
|
+
scope: Scope,
|
|
3870
|
+
description: Named,
|
|
3871
|
+
availability: Optional$4(Named),
|
|
3872
|
+
service: Named,
|
|
3873
|
+
member: Named,
|
|
3874
|
+
direction: Union([Literal("client-to-server"), Literal("server-to-client")]),
|
|
3875
|
+
kind: Union([
|
|
3876
|
+
Literal("method"),
|
|
3877
|
+
Literal("state"),
|
|
3878
|
+
Literal("channel")
|
|
3879
|
+
]),
|
|
3880
|
+
input: Schema,
|
|
3881
|
+
output: Optional$4(Schema),
|
|
3882
|
+
errors: Optional$4(Schema)
|
|
3883
|
+
})),
|
|
3884
|
+
/** Explicitly enumerate dynamic values whose shape is supplied at runtime. */
|
|
3885
|
+
dynamic: _Array_(String$1({ minLength: 1 })),
|
|
3886
|
+
gaps: Optional$4(_Array_(Named))
|
|
3887
|
+
});
|
|
3888
|
+
function defineApiContract(contract) {
|
|
3889
|
+
return contract;
|
|
3890
|
+
}
|
|
3891
|
+
//#endregion
|
|
3892
|
+
//#region ../../core/po-core/src/schemas/remoteApiContracts.ts
|
|
3893
|
+
const Text = String$1();
|
|
3894
|
+
const NumberValue = Number$1();
|
|
3895
|
+
const Optional = Optional$4;
|
|
3896
|
+
const Flag = Boolean();
|
|
3897
|
+
const JsonObject = Record(Text, Unknown({ description: "WebAuthn ceremony fields supplied and verified by the installed WebAuthn implementation." }));
|
|
3898
|
+
const Tunnel = Union([_Object_({ kind: Literal("quick") }), _Object_({
|
|
3899
|
+
kind: Literal("named"),
|
|
3900
|
+
hostname: Text,
|
|
3901
|
+
name: Optional(Text),
|
|
3902
|
+
tokenFile: Optional(Text),
|
|
3903
|
+
configFile: Optional(Text)
|
|
3904
|
+
})]);
|
|
3905
|
+
const Settings = _Object_({
|
|
3906
|
+
autoCloseEnabled: Flag,
|
|
3907
|
+
autoCloseMinutes: NumberValue,
|
|
3908
|
+
sessionExpiryEnabled: Flag,
|
|
3909
|
+
idleMinutes: NumberValue,
|
|
3910
|
+
absoluteHours: NumberValue,
|
|
3911
|
+
tunnel: Tunnel
|
|
3912
|
+
});
|
|
3913
|
+
const State = _Object_({
|
|
3914
|
+
status: Union([
|
|
3915
|
+
Literal("off"),
|
|
3916
|
+
Literal("starting"),
|
|
3917
|
+
Literal("on"),
|
|
3918
|
+
Literal("failed")
|
|
3919
|
+
]),
|
|
3920
|
+
publicUrl: Optional(Text),
|
|
3921
|
+
startedAt: Optional(Text),
|
|
3922
|
+
closesAt: Optional(Text),
|
|
3923
|
+
error: Optional(Text),
|
|
3924
|
+
devices: _Array_(_Object_({
|
|
3925
|
+
id: Text,
|
|
3926
|
+
label: Text,
|
|
3927
|
+
userAgent: Text,
|
|
3928
|
+
createdAt: Text,
|
|
3929
|
+
lastSeenAt: Text,
|
|
3930
|
+
self: Flag
|
|
3931
|
+
})),
|
|
3932
|
+
pending: _Array_(_Object_({
|
|
3933
|
+
id: Text,
|
|
3934
|
+
userAgent: Text,
|
|
3935
|
+
edgeIp: Text,
|
|
3936
|
+
createdAt: Text,
|
|
3937
|
+
expiresAt: Text
|
|
3938
|
+
})),
|
|
3939
|
+
trustedDevices: _Array_(_Object_({
|
|
3940
|
+
id: Text,
|
|
3941
|
+
label: Text,
|
|
3942
|
+
platform: Union([Literal("ios"), Literal("android")]),
|
|
3943
|
+
createdAt: Text,
|
|
3944
|
+
lastSeenAt: Text,
|
|
3945
|
+
self: Flag
|
|
3946
|
+
})),
|
|
3947
|
+
settings: Settings
|
|
3948
|
+
});
|
|
3949
|
+
const StateResponse = _Object_({ state: State });
|
|
3950
|
+
const Trust = _Object_({
|
|
3951
|
+
publicKey: Text,
|
|
3952
|
+
fingerprint: Text,
|
|
3953
|
+
revision: NumberValue
|
|
3954
|
+
});
|
|
3955
|
+
const Begun = _Object_({
|
|
3956
|
+
ceremonyId: Text,
|
|
3957
|
+
options: JsonObject
|
|
3958
|
+
});
|
|
3959
|
+
const DeviceKeyBegun = _Object_({
|
|
3960
|
+
ceremonyId: Text,
|
|
3961
|
+
challenge: Text,
|
|
3962
|
+
kind: Literal("device-key")
|
|
3963
|
+
});
|
|
3964
|
+
const ChannelKeys = _Object_({
|
|
3965
|
+
session: Text,
|
|
3966
|
+
protocol: Text,
|
|
3967
|
+
http: Text
|
|
3968
|
+
});
|
|
3969
|
+
const Finish = _Object_({
|
|
3970
|
+
ceremonyId: Text,
|
|
3971
|
+
response: JsonObject
|
|
3972
|
+
});
|
|
3973
|
+
const SealedEnvelopeSchema = _Object_({
|
|
3974
|
+
v: Literal(1),
|
|
3975
|
+
n: Text,
|
|
3976
|
+
c: Text
|
|
3977
|
+
});
|
|
3978
|
+
_Object_({
|
|
3979
|
+
v: Literal(1),
|
|
3980
|
+
method: Text,
|
|
3981
|
+
target: Text,
|
|
3982
|
+
headers: _Array_(Tuple([Text, Text])),
|
|
3983
|
+
body: Optional(Text)
|
|
3984
|
+
});
|
|
3985
|
+
_Object_({
|
|
3986
|
+
v: Literal(1),
|
|
3987
|
+
status: NumberValue,
|
|
3988
|
+
headers: _Array_(Tuple([Text, Text])),
|
|
3989
|
+
body: Text
|
|
3990
|
+
});
|
|
3991
|
+
const route = (id, path, method, result, input, extra = {}) => ({
|
|
3992
|
+
id: `remote.${id}`,
|
|
3993
|
+
path: `/api/remote${path}`,
|
|
3994
|
+
method,
|
|
3995
|
+
scope: "global",
|
|
3996
|
+
authentication: "owner",
|
|
3997
|
+
description: `Remote Control ${id}.`,
|
|
3998
|
+
availability: "Global host provides Remote Control. Tunnel routes additionally enforce device, origin and step-up policy.",
|
|
3999
|
+
responses: {
|
|
4000
|
+
...jsonApiResponses(result),
|
|
4001
|
+
"429": {
|
|
4002
|
+
description: "Rate limit exceeded",
|
|
4003
|
+
schema: ApiErrorSchema
|
|
4004
|
+
}
|
|
4005
|
+
},
|
|
4006
|
+
...input ? { body: {
|
|
4007
|
+
contentType: "application/json",
|
|
4008
|
+
required: true,
|
|
4009
|
+
schema: input
|
|
4010
|
+
} } : {},
|
|
4011
|
+
...extra
|
|
4012
|
+
});
|
|
4013
|
+
const direct = [
|
|
4014
|
+
route("state", "", "GET", StateResponse),
|
|
4015
|
+
route("enable", "/enable", "POST", StateResponse),
|
|
4016
|
+
route("disable", "/disable", "POST", StateResponse, void 0, { responses: {
|
|
4017
|
+
...jsonApiResponses(StateResponse),
|
|
4018
|
+
"202": {
|
|
4019
|
+
description: "Tunnel closing",
|
|
4020
|
+
schema: _Object_({ status: Literal("closing") })
|
|
4021
|
+
}
|
|
4022
|
+
} }),
|
|
4023
|
+
route("codes", "/codes", "POST", _Object_({
|
|
4024
|
+
...Trust.properties,
|
|
4025
|
+
code: Text,
|
|
4026
|
+
manualCode: Text,
|
|
4027
|
+
pairUrl: Text,
|
|
4028
|
+
expiresAt: Text
|
|
4029
|
+
}), void 0, { responses: jsonApiResponses(_Object_({
|
|
4030
|
+
...Trust.properties,
|
|
4031
|
+
code: Text,
|
|
4032
|
+
manualCode: Text,
|
|
4033
|
+
pairUrl: Text,
|
|
4034
|
+
expiresAt: Text
|
|
4035
|
+
}), 201) }),
|
|
4036
|
+
route("approve", "/pairing/{id}/approve", "POST", StateResponse),
|
|
4037
|
+
route("deny", "/pairing/{id}/deny", "POST", StateResponse),
|
|
4038
|
+
route("revoke", "/devices/{id}", "DELETE", StateResponse),
|
|
4039
|
+
route("settings", "/settings", "PUT", _Object_({ settings: Settings }), Partial(Settings)),
|
|
4040
|
+
route("passkeys", "/passkeys", "GET", _Object_({
|
|
4041
|
+
support: Union([_Object_({
|
|
4042
|
+
supported: Literal(true),
|
|
4043
|
+
rpId: Text
|
|
4044
|
+
}), _Object_({
|
|
4045
|
+
supported: Literal(false),
|
|
4046
|
+
reason: Text
|
|
4047
|
+
})]),
|
|
4048
|
+
credentials: _Array_(_Object_({
|
|
4049
|
+
id: Text,
|
|
4050
|
+
label: Text,
|
|
4051
|
+
createdAt: Text,
|
|
4052
|
+
lastUsedAt: Text
|
|
4053
|
+
}))
|
|
4054
|
+
})),
|
|
4055
|
+
route("passkeys.remove", "/passkeys/{id}", "DELETE", ApiOkSchema),
|
|
4056
|
+
route("register.begin", "/passkeys/register/begin", "POST", Begun, void 0, { authentication: "device" }),
|
|
4057
|
+
route("register.finish", "/passkeys/register/finish", "POST", _Object_({ id: Text }), Finish, { authentication: "device" }),
|
|
4058
|
+
route("authenticate.begin", "/passkeys/authenticate/begin", "POST", Begun, void 0, { authentication: "none" }),
|
|
4059
|
+
route("authenticate.finish", "/passkeys/authenticate/finish", "POST", _Object_({
|
|
4060
|
+
ok: Literal(true),
|
|
4061
|
+
hostPublicKey: Text
|
|
4062
|
+
}), Finish, { authentication: "none" }),
|
|
4063
|
+
route("challenge", "/challenge", "POST", Union([Begun, DeviceKeyBegun]), _Object_({ action: Text }), { authentication: "device" }),
|
|
4064
|
+
route("trusted-devices.register", "/trusted-devices", "POST", _Object_({ trustedDeviceId: Text }), _Object_({
|
|
4065
|
+
identityPublicKey: Text,
|
|
4066
|
+
stepUpPublicKey: Text,
|
|
4067
|
+
label: Text,
|
|
4068
|
+
platform: Union([Literal("ios"), Literal("android")]),
|
|
4069
|
+
identityProof: Text,
|
|
4070
|
+
stepUpProof: Text
|
|
4071
|
+
}), {
|
|
4072
|
+
authentication: "device",
|
|
4073
|
+
description: "Registers a native device from a sealed, QR-approved pairing session.",
|
|
4074
|
+
responses: jsonApiResponses(_Object_({ trustedDeviceId: Text }), 201)
|
|
4075
|
+
}),
|
|
4076
|
+
route("trusted-devices.revoke", "/trusted-devices/{id}", "DELETE", StateResponse, void 0, { description: "Revokes a trusted native device. Local callers, or sealed callers with verified step-up." }),
|
|
4077
|
+
route("device-auth.challenge", "/device-auth/challenge", "POST", _Object_({
|
|
4078
|
+
challengeId: Text,
|
|
4079
|
+
challenge: Text,
|
|
4080
|
+
hostPublicKey: Text,
|
|
4081
|
+
attestation: Text
|
|
4082
|
+
}), _Object_({
|
|
4083
|
+
trustedDeviceId: Text,
|
|
4084
|
+
nonce: Text
|
|
4085
|
+
}), { authentication: "none" }),
|
|
4086
|
+
route("device-auth.authenticate", "/device-auth/authenticate", "POST", _Object_({ ok: Literal(true) }), _Object_({
|
|
4087
|
+
challengeId: Text,
|
|
4088
|
+
trustedDeviceId: Text,
|
|
4089
|
+
signature: Text,
|
|
4090
|
+
channels: ChannelKeys
|
|
4091
|
+
}), { authentication: "none" }),
|
|
4092
|
+
route("channel", "/channel", "POST", ApiOkSchema, _Object_({
|
|
4093
|
+
clientPublicKey: Text,
|
|
4094
|
+
scope: Union([
|
|
4095
|
+
Literal("session"),
|
|
4096
|
+
Literal("protocol"),
|
|
4097
|
+
Literal("http")
|
|
4098
|
+
])
|
|
4099
|
+
}), { authentication: "device" }),
|
|
4100
|
+
route("request", "/request", "POST", SealedEnvelopeSchema, SealedEnvelopeSchema, {
|
|
4101
|
+
authentication: "device",
|
|
4102
|
+
description: "Sealed HTTP gateway. Decrypted requests/responses use the SealedHttpRequest and SealedHttpResponse envelopes."
|
|
4103
|
+
}),
|
|
4104
|
+
route("pair", "/pair", "POST", _Object_({
|
|
4105
|
+
requestId: Text,
|
|
4106
|
+
status: Literal("pending")
|
|
4107
|
+
}), _Object_({ code: String$1({ minLength: 1 }) }), {
|
|
4108
|
+
authentication: "none",
|
|
4109
|
+
responses: {
|
|
4110
|
+
...jsonApiResponses(_Object_({
|
|
4111
|
+
requestId: Text,
|
|
4112
|
+
status: Literal("pending")
|
|
4113
|
+
}), 202),
|
|
4114
|
+
"410": {
|
|
4115
|
+
description: "Pairing code is no longer valid",
|
|
4116
|
+
schema: ApiErrorSchema
|
|
4117
|
+
}
|
|
4118
|
+
}
|
|
4119
|
+
}),
|
|
4120
|
+
route("pair.status", "/pair/status", "GET", _Object_({
|
|
4121
|
+
status: Union([
|
|
4122
|
+
Literal("pending"),
|
|
4123
|
+
Literal("approved"),
|
|
4124
|
+
Literal("denied"),
|
|
4125
|
+
Literal("expired"),
|
|
4126
|
+
Literal("consumed")
|
|
4127
|
+
]),
|
|
4128
|
+
bundleTrust: Optional(Trust),
|
|
4129
|
+
hostPublicKey: Optional(Text)
|
|
4130
|
+
}), void 0, {
|
|
4131
|
+
authentication: "none",
|
|
4132
|
+
parameters: [{
|
|
4133
|
+
name: "request",
|
|
4134
|
+
in: "query",
|
|
4135
|
+
required: true,
|
|
4136
|
+
schema: Text
|
|
4137
|
+
}]
|
|
4138
|
+
})
|
|
4139
|
+
];
|
|
4140
|
+
const remoteHttpContracts = [
|
|
4141
|
+
route("frontend", "/frontend", "POST", ApiOkSchema, _Object_({ origin: Text }), {
|
|
4142
|
+
authentication: "owner",
|
|
4143
|
+
availability: "Internal loopback frontend registration; blocked by the browser proxy.",
|
|
4144
|
+
parameters: [{
|
|
4145
|
+
name: "x-po-web-registration",
|
|
4146
|
+
in: "header",
|
|
4147
|
+
required: true,
|
|
4148
|
+
schema: Text
|
|
4149
|
+
}]
|
|
4150
|
+
}),
|
|
4151
|
+
...direct,
|
|
4152
|
+
...direct.map((operation) => ({
|
|
4153
|
+
...operation,
|
|
4154
|
+
id: `${operation.id}.plugin`,
|
|
4155
|
+
basePath: "remote",
|
|
4156
|
+
path: operation.path.slice(11) || "/",
|
|
4157
|
+
authentication: "owner",
|
|
4158
|
+
availability: "Global Remote Control plugin mount, reached through the authenticated headless listener."
|
|
4159
|
+
})),
|
|
4160
|
+
{
|
|
4161
|
+
id: "remote.pair.page",
|
|
4162
|
+
scope: "global",
|
|
4163
|
+
path: "/pair",
|
|
4164
|
+
method: "GET",
|
|
4165
|
+
authentication: "none",
|
|
4166
|
+
availability: "Remote listener only",
|
|
4167
|
+
description: "Pairing and passkey bootstrap page.",
|
|
4168
|
+
responses: { "200": {
|
|
4169
|
+
description: "Pairing page",
|
|
4170
|
+
contentType: "text/html",
|
|
4171
|
+
schema: Text
|
|
4172
|
+
} }
|
|
4173
|
+
}
|
|
4174
|
+
];
|
|
4175
|
+
const Asset = _Object_({
|
|
4176
|
+
path: Text,
|
|
4177
|
+
sha256: String$1({ pattern: "^[a-f0-9]{64}$" }),
|
|
4178
|
+
byteLength: Integer({ minimum: 0 }),
|
|
4179
|
+
contentType: Text
|
|
4180
|
+
});
|
|
4181
|
+
const Signed = _Object_({
|
|
4182
|
+
manifest: _Object_({
|
|
4183
|
+
version: Literal(2),
|
|
4184
|
+
revision: Integer({ minimum: 1 }),
|
|
4185
|
+
builtAt: NumberValue,
|
|
4186
|
+
assets: _Array_(Asset)
|
|
4187
|
+
}),
|
|
4188
|
+
signature: Text,
|
|
4189
|
+
publicKey: Text
|
|
4190
|
+
});
|
|
4191
|
+
const bundleHttpContracts = [...["/bundle-manifest.json", "/api/web-plugins/{id}/{revision}/manifest"].flatMap((path) => ["GET", "HEAD"].map((method) => ({
|
|
4192
|
+
id: `bundle.${path}.${method}`,
|
|
4193
|
+
scope: "global",
|
|
4194
|
+
path,
|
|
4195
|
+
method,
|
|
4196
|
+
authentication: "owner",
|
|
4197
|
+
availability: "Host publishes a web bundle",
|
|
4198
|
+
description: "Read an immutable signed browser bundle manifest.",
|
|
4199
|
+
responses: method === "HEAD" ? {
|
|
4200
|
+
"200": { description: "Manifest response headers" },
|
|
4201
|
+
"404": { description: "Bundle not published" }
|
|
4202
|
+
} : jsonApiResponses(Signed)
|
|
4203
|
+
}))), ...["/bundle-assets/{revision}/{assetPath}", "/api/web-plugins/{id}/{revision}/assets/{assetPath}"].flatMap((path) => ["GET", "HEAD"].map((method) => ({
|
|
4204
|
+
id: `asset.${path}.${method}`,
|
|
4205
|
+
scope: "global",
|
|
4206
|
+
path,
|
|
4207
|
+
method,
|
|
4208
|
+
authentication: "owner",
|
|
4209
|
+
availability: "Host publishes a web bundle",
|
|
4210
|
+
description: "Read an asset from the signed manifest. assetPath may contain multiple path segments.",
|
|
4211
|
+
responses: {
|
|
4212
|
+
"200": {
|
|
4213
|
+
description: "Manifest-listed asset, original MIME type",
|
|
4214
|
+
...method === "GET" ? {
|
|
4215
|
+
contentType: "*/*",
|
|
4216
|
+
schema: String$1({ contentEncoding: "binary" })
|
|
4217
|
+
} : {}
|
|
4218
|
+
},
|
|
4219
|
+
"404": { description: "Asset not published" }
|
|
4220
|
+
}
|
|
4221
|
+
})))];
|
|
4222
|
+
//#endregion
|
|
4223
|
+
//#region ../../core/po-core/src/schemas/transportApiContracts.ts
|
|
4224
|
+
/** The Chord release whose link frames this file describes (link protocol 4). */
|
|
4225
|
+
const CHORD_WIRE_VERSION = "1.3.0";
|
|
4226
|
+
const S = String$1({ minLength: 1 });
|
|
4227
|
+
const Json = Unknown({ description: "JSON value; its application shape is defined by the addressed contract member." });
|
|
4228
|
+
const Id = Integer({ minimum: 1 });
|
|
4229
|
+
const ErrorCode = Union([
|
|
4230
|
+
"aborted",
|
|
4231
|
+
"contract_mismatch",
|
|
4232
|
+
"forbidden",
|
|
4233
|
+
"gone",
|
|
4234
|
+
"invalid",
|
|
4235
|
+
"not_in_variant",
|
|
4236
|
+
"not_ready",
|
|
4237
|
+
"released",
|
|
4238
|
+
"superseded",
|
|
4239
|
+
"unavailable",
|
|
4240
|
+
"upgrade_conflict",
|
|
4241
|
+
"upgrade_required"
|
|
4242
|
+
].map((code) => Literal(code)));
|
|
4243
|
+
const WireError = _Object_({
|
|
4244
|
+
code: ErrorCode,
|
|
4245
|
+
message: String$1(),
|
|
4246
|
+
reason: Optional$4(String$1())
|
|
4247
|
+
});
|
|
4248
|
+
const Segment = Union([String$1(), Integer({ minimum: 0 })]);
|
|
4249
|
+
const Path = _Array_(Segment);
|
|
4250
|
+
const PathRef = Union([Path, Integer({ minimum: 0 })]);
|
|
4251
|
+
const NonemptyPathRef = Union([_Array_(Segment, { minItems: 1 }), Integer({ minimum: 0 })]);
|
|
4252
|
+
const Index = Integer({ minimum: 0 });
|
|
4253
|
+
const ChordWireOpSchema = Union([
|
|
4254
|
+
Tuple([Literal("r"), Json]),
|
|
4255
|
+
Tuple([
|
|
4256
|
+
Literal("s"),
|
|
4257
|
+
NonemptyPathRef,
|
|
4258
|
+
Json
|
|
4259
|
+
]),
|
|
4260
|
+
Tuple([Literal("s"), Json]),
|
|
4261
|
+
Tuple([Literal("d"), NonemptyPathRef]),
|
|
4262
|
+
Tuple([Literal("d")]),
|
|
4263
|
+
Tuple([
|
|
4264
|
+
Literal("a"),
|
|
4265
|
+
NonemptyPathRef,
|
|
4266
|
+
String$1()
|
|
4267
|
+
]),
|
|
4268
|
+
Tuple([Literal("a"), String$1()]),
|
|
4269
|
+
Tuple([
|
|
4270
|
+
Literal("t"),
|
|
4271
|
+
NonemptyPathRef,
|
|
4272
|
+
Index
|
|
4273
|
+
]),
|
|
4274
|
+
Tuple([Literal("t"), Index]),
|
|
4275
|
+
Tuple([
|
|
4276
|
+
Literal("p"),
|
|
4277
|
+
PathRef,
|
|
4278
|
+
Index,
|
|
4279
|
+
Index,
|
|
4280
|
+
_Array_(Json)
|
|
4281
|
+
]),
|
|
4282
|
+
Tuple([
|
|
4283
|
+
Literal("p"),
|
|
4284
|
+
Index,
|
|
4285
|
+
Index,
|
|
4286
|
+
_Array_(Json)
|
|
4287
|
+
]),
|
|
4288
|
+
Tuple([
|
|
4289
|
+
Literal("m"),
|
|
4290
|
+
PathRef,
|
|
4291
|
+
_Array_(Index)
|
|
4292
|
+
]),
|
|
4293
|
+
Tuple([Literal("m"), _Array_(Index)]),
|
|
4294
|
+
Tuple([
|
|
4295
|
+
Literal("#"),
|
|
4296
|
+
Index,
|
|
4297
|
+
Path
|
|
4298
|
+
])
|
|
4299
|
+
], { description: "Chord delta tuples. Path dictionary references and omitted paths depend on earlier operations in this subscription; decode with the Chord delta decoder." });
|
|
4300
|
+
const Hello = (kind) => _Object_({
|
|
4301
|
+
t: Literal("hello"),
|
|
4302
|
+
protocol: Optional$4(Integer({ minimum: 1 })),
|
|
4303
|
+
name: String$1(),
|
|
4304
|
+
kind,
|
|
4305
|
+
codeVersion: Integer({ minimum: 0 }),
|
|
4306
|
+
acks: Optional$4(Boolean())
|
|
4307
|
+
});
|
|
4308
|
+
const Ack = _Object_({
|
|
4309
|
+
t: Literal("ack"),
|
|
4310
|
+
n: Integer({ minimum: 1 })
|
|
4311
|
+
});
|
|
4312
|
+
const Ping = _Object_({
|
|
4313
|
+
t: Literal("ping"),
|
|
4314
|
+
n: Integer()
|
|
4315
|
+
});
|
|
4316
|
+
const Pong = _Object_({
|
|
4317
|
+
t: Literal("pong"),
|
|
4318
|
+
n: Integer()
|
|
4319
|
+
});
|
|
4320
|
+
const Bye = _Object_({
|
|
4321
|
+
t: Literal("bye"),
|
|
4322
|
+
reason: Optional$4(String$1())
|
|
4323
|
+
});
|
|
4324
|
+
/** Frames a client (browser or native app) sends on its link. */
|
|
4325
|
+
const ChordClientFrameSchema = Union([
|
|
4326
|
+
Hello(Literal("client")),
|
|
4327
|
+
Ack,
|
|
4328
|
+
_Object_({
|
|
4329
|
+
t: Literal("hold"),
|
|
4330
|
+
id: Id,
|
|
4331
|
+
at: String$1(),
|
|
4332
|
+
token: Json,
|
|
4333
|
+
input: Json,
|
|
4334
|
+
state: Optional$4(Literal(false)),
|
|
4335
|
+
again: Optional$4(Literal(true))
|
|
4336
|
+
}),
|
|
4337
|
+
_Object_({
|
|
4338
|
+
t: Literal("release"),
|
|
4339
|
+
id: Id
|
|
4340
|
+
}),
|
|
4341
|
+
_Object_({
|
|
4342
|
+
t: Literal("call"),
|
|
4343
|
+
id: Id,
|
|
4344
|
+
hold: Id,
|
|
4345
|
+
member: S,
|
|
4346
|
+
args: Optional$4(Json)
|
|
4347
|
+
}),
|
|
4348
|
+
_Object_({
|
|
4349
|
+
t: Literal("cancel"),
|
|
4350
|
+
id: Id
|
|
4351
|
+
}),
|
|
4352
|
+
_Object_({
|
|
4353
|
+
t: Literal("sub"),
|
|
4354
|
+
hold: Id
|
|
4355
|
+
}),
|
|
4356
|
+
_Object_({
|
|
4357
|
+
t: Literal("unsub"),
|
|
4358
|
+
hold: Id
|
|
4359
|
+
}),
|
|
4360
|
+
_Object_({
|
|
4361
|
+
t: Literal("root_end"),
|
|
4362
|
+
rootId: String$1()
|
|
4363
|
+
}),
|
|
4364
|
+
Ping,
|
|
4365
|
+
Pong,
|
|
4366
|
+
Bye
|
|
4367
|
+
]);
|
|
4368
|
+
/** Frames the Po server sends to a client link. */
|
|
4369
|
+
const ChordServerFrameSchema = Union([
|
|
4370
|
+
Hello(String$1()),
|
|
4371
|
+
Ack,
|
|
4372
|
+
_Object_({
|
|
4373
|
+
t: Literal("shape"),
|
|
4374
|
+
id: Id,
|
|
4375
|
+
variant: Optional$4(String$1()),
|
|
4376
|
+
members: _Array_(String$1()),
|
|
4377
|
+
contract: String$1(),
|
|
4378
|
+
state: _Array_(S)
|
|
4379
|
+
}),
|
|
4380
|
+
_Object_({
|
|
4381
|
+
t: Literal("gone"),
|
|
4382
|
+
id: Id,
|
|
4383
|
+
error: WireError
|
|
4384
|
+
}),
|
|
4385
|
+
_Object_({
|
|
4386
|
+
t: Literal("result"),
|
|
4387
|
+
id: Id,
|
|
4388
|
+
value: Optional$4(Json),
|
|
4389
|
+
error: Optional$4(WireError)
|
|
4390
|
+
}),
|
|
4391
|
+
_Object_({
|
|
4392
|
+
t: Literal("state"),
|
|
4393
|
+
hold: Id,
|
|
4394
|
+
m: S,
|
|
4395
|
+
as: Union([
|
|
4396
|
+
Literal("snap"),
|
|
4397
|
+
Literal("reset"),
|
|
4398
|
+
Literal("ops"),
|
|
4399
|
+
Literal("error")
|
|
4400
|
+
]),
|
|
4401
|
+
value: Optional$4(Json),
|
|
4402
|
+
ops: Optional$4(_Array_(ChordWireOpSchema)),
|
|
4403
|
+
error: Optional$4(WireError)
|
|
4404
|
+
}),
|
|
4405
|
+
Ping,
|
|
4406
|
+
Pong,
|
|
4407
|
+
Bye
|
|
4408
|
+
]);
|
|
4409
|
+
const transportSocketContracts = [
|
|
4410
|
+
{
|
|
4411
|
+
id: "chord.client",
|
|
4412
|
+
scope: "global",
|
|
4413
|
+
service: "$chord",
|
|
4414
|
+
member: "client",
|
|
4415
|
+
direction: "client-to-server",
|
|
4416
|
+
kind: "channel",
|
|
4417
|
+
input: ChordClientFrameSchema,
|
|
4418
|
+
description: `Chord ${CHORD_WIRE_VERSION} link frame, one JSON text message each, sealed for remote delivery. Hold \`po.hub\` ({}) and \`po.session\` ({ sessionId }) at host \`server\`.`
|
|
4419
|
+
},
|
|
4420
|
+
{
|
|
4421
|
+
id: "chord.server",
|
|
4422
|
+
scope: "global",
|
|
4423
|
+
service: "$chord",
|
|
4424
|
+
member: "server",
|
|
4425
|
+
direction: "server-to-client",
|
|
4426
|
+
kind: "channel",
|
|
4427
|
+
input: ChordServerFrameSchema,
|
|
4428
|
+
description: "Chord link frame. Results correlate by call id; state frames by hold id and member."
|
|
4429
|
+
},
|
|
4430
|
+
{
|
|
4431
|
+
id: "plugin.invoke",
|
|
4432
|
+
scope: "global",
|
|
4433
|
+
service: "po.hub",
|
|
4434
|
+
member: "invoke",
|
|
4435
|
+
direction: "client-to-server",
|
|
4436
|
+
kind: "method",
|
|
4437
|
+
input: PoPluginCallSchema,
|
|
4438
|
+
output: Json,
|
|
4439
|
+
errors: WireError,
|
|
4440
|
+
description: "Invoke the selected scoped plugin method. Its declaration supplies input and output shapes."
|
|
4441
|
+
}
|
|
4442
|
+
];
|
|
4443
|
+
[
|
|
4444
|
+
...headlessHttpContracts,
|
|
4445
|
+
...machineHttpContracts,
|
|
4446
|
+
...sessionHttpContracts,
|
|
4447
|
+
...remoteHttpContracts,
|
|
4448
|
+
...bundleHttpContracts
|
|
4449
|
+
], [...sessionSocketContracts, ...transportSocketContracts];
|
|
4450
|
+
//#endregion
|
|
4451
|
+
export { oneOf as $, resolveHost as A, asChordError as B, coverage as C, placedOn as D, opaque as E, cleaned as F, compile as G, invalid as H, deepEqual as I, int as J, arr as K, normalize as L, assertValid as M, canonicalIdentity as N, placementText as O, canonicalJson as P, obj as Q, CHORD_ERROR_CODES as R, contractFromDescription as S, local as T, isChordError as U, forbidden as V, runAll as W, map as X, lit as Y, num as Z, PO_SERVER_HOST as _, PoThreadContract as a, definePoPluginMethod as at, DescriptionSchema as b, HubNoticeSchema as c, PoHubContract as d, opt as et, PoHubRevisionsContract as f, PoChannelsStateSchema as g, PoChannelsContract as h, SessionServiceStateSchema as i, createPoPluginRegistry as it, takesNoArgs as j, remote as k, HubRevisionsSchema as l, jsonApiResponses as m, SessionMethodSchemas as n, union as nt, PoThreadFrameSchema as o, SessionSummarySchema as p, bool as q, SessionMethods as r, unknown as rt, HubCompositionsSchema as s, defineApiContract as t, str as tt, HubWorkspaceSchema as u, chordSchema as v, hostNamed as w, bind as x, chordStates as y, ChordError as z };
|