dsh-edge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +183 -0
- package/README.zh.md +183 -0
- package/THIRD_PARTY_NOTICES.md +199 -0
- package/dist/_headers +3 -0
- package/dist/assets/fonts/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/fonts/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/fonts/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/fonts/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/fonts/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/index-C-1AiF3k.js +112 -0
- package/dist/assets/index-CSGf6Qzd.css +1 -0
- package/dist/assets/langs/c-BIGW1oBm.js +2 -0
- package/dist/assets/langs/cpp-DIPi6g--.js +2 -0
- package/dist/assets/langs/csharp-DSvCPggb.js +2 -0
- package/dist/assets/langs/css-CLj8gQPS.js +2 -0
- package/dist/assets/langs/go-C27-OAKa.js +2 -0
- package/dist/assets/langs/html-CfGypltT.js +2 -0
- package/dist/assets/langs/ini-BEwlwnbL.js +2 -0
- package/dist/assets/langs/java-CylS5w8V.js +2 -0
- package/dist/assets/langs/kotlin-BdnUsdx6.js +2 -0
- package/dist/assets/langs/less-B1dDrJ26.js +2 -0
- package/dist/assets/langs/lua-BaeVxFsk.js +2 -0
- package/dist/assets/langs/markdown-Cvjx9yec.js +2 -0
- package/dist/assets/langs/mdx-Cmh6b_Ma.js +2 -0
- package/dist/assets/langs/php-D-uCvoST.js +2 -0
- package/dist/assets/langs/python-B6aJPvgy.js +2 -0
- package/dist/assets/langs/ruby-DEItuUFs.js +2 -0
- package/dist/assets/langs/rust-B1yitclQ.js +2 -0
- package/dist/assets/langs/scss-D5BDwBP9.js +2 -0
- package/dist/assets/langs/sql-CRqJ_cUM.js +2 -0
- package/dist/assets/langs/swift-D82vCrfD.js +2 -0
- package/dist/assets/langs/toml-vGWfd6FD.js +2 -0
- package/dist/assets/langs/xml-sdJ4AIDG.js +2 -0
- package/dist/assets/langs/yaml-Buea-lGh.js +2 -0
- package/dist/assets/vendor-Cjbwl5VI.js +411 -0
- package/dist/assets/vendor-CjyC-hUb.css +1 -0
- package/dist/favicon.svg +8 -0
- package/dist/index.html +35 -0
- package/dist/manifest.webmanifest +16 -0
- package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +420 -0
- package/dist/plugins/@deepseek-ai/dsh-api-remotes/client.js +5937 -0
- package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +10207 -0
- package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +1231 -0
- package/dist/plugins/@deepseek-ai/dsh-client-modules/client.js +259 -0
- package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +10539 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +1725 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +1116 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +9832 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +373 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-edge/client.js +549 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +859 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +280 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +456 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +804 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +461 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings/client.js +254 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +609 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +292 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +327 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +710 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +1312 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +1630 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +7370 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +700 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +474 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +2426 -0
- package/dist/plugins/@deepseek-ai/dsh-typert-registry/client.js +1372 -0
- package/package.json +97 -0
- package/scripts/assemble-web.mjs +230 -0
- package/scripts/bundle-size.d.mts +2 -0
- package/scripts/bundle-size.mjs +26 -0
- package/scripts/bundle.mjs +53 -0
- package/scripts/cli.d.mts +39 -0
- package/scripts/cli.mjs +496 -0
- package/scripts/install.d.mts +149 -0
- package/scripts/install.mjs +989 -0
- package/scripts/legal-files.mjs +24 -0
- package/scripts/verify-packed.mjs +32 -0
- package/scripts/wrangler-config.d.mts +18 -0
- package/scripts/wrangler-config.mjs +84 -0
- package/src/agent.ts +119 -0
- package/src/auth.ts +352 -0
- package/src/deepseek.ts +231 -0
- package/src/deployment.ts +147 -0
- package/src/direct-shell-core-empty.ts +10 -0
- package/src/direct-shell-protocol.ts +5 -0
- package/src/direct-shell.ts +341 -0
- package/src/do-session-persistence.ts +1064 -0
- package/src/edge-api.ts +796 -0
- package/src/edge-credentials.ts +56 -0
- package/src/edge-remotes.ts +41 -0
- package/src/edge-workspace-store.ts +339 -0
- package/src/http.ts +212 -0
- package/src/index.ts +196 -0
- package/src/instance.ts +1007 -0
- package/src/isolated-direct-shell-unavailable.ts +11 -0
- package/src/protocol.ts +39 -0
- package/src/release.ts +9 -0
- package/src/session-store.ts +1110 -0
- package/src/sse.ts +86 -0
- package/src/web-search.ts +38 -0
- package/src/workspace.ts +270 -0
- package/wrangler.jsonc +56 -0
|
@@ -0,0 +1,1372 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@deepseek-ai/dsh-typert-registry",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
|
|
8
|
+
//#region ../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js
|
|
9
|
+
function getEnumValues(entries) {
|
|
10
|
+
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
11
|
+
return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
|
|
12
|
+
}
|
|
13
|
+
"captureStackTrace" in Error && Error.captureStackTrace;
|
|
14
|
+
Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, -Number.MAX_VALUE, Number.MAX_VALUE;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region ../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/registries.js
|
|
17
|
+
var _a;
|
|
18
|
+
var $ZodRegistry = class {
|
|
19
|
+
constructor() {
|
|
20
|
+
this._map = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
this._idmap = /* @__PURE__ */ new Map();
|
|
22
|
+
}
|
|
23
|
+
add(schema, ..._meta) {
|
|
24
|
+
const meta = _meta[0];
|
|
25
|
+
this._map.set(schema, meta);
|
|
26
|
+
if (meta && typeof meta === "object" && "id" in meta) this._idmap.set(meta.id, schema);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
clear() {
|
|
30
|
+
this._map = /* @__PURE__ */ new WeakMap();
|
|
31
|
+
this._idmap = /* @__PURE__ */ new Map();
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
remove(schema) {
|
|
35
|
+
const meta = this._map.get(schema);
|
|
36
|
+
if (meta && typeof meta === "object" && "id" in meta) this._idmap.delete(meta.id);
|
|
37
|
+
this._map.delete(schema);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
get(schema) {
|
|
41
|
+
const p = schema._zod.parent;
|
|
42
|
+
if (p) {
|
|
43
|
+
const pm = { ...this.get(p) ?? {} };
|
|
44
|
+
delete pm.id;
|
|
45
|
+
const f = {
|
|
46
|
+
...pm,
|
|
47
|
+
...this._map.get(schema)
|
|
48
|
+
};
|
|
49
|
+
return Object.keys(f).length ? f : void 0;
|
|
50
|
+
}
|
|
51
|
+
return this._map.get(schema);
|
|
52
|
+
}
|
|
53
|
+
has(schema) {
|
|
54
|
+
return this._map.has(schema);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function registry() {
|
|
58
|
+
return new $ZodRegistry();
|
|
59
|
+
}
|
|
60
|
+
(_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
|
|
61
|
+
const globalRegistry = globalThis.__zod_globalRegistry;
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region ../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/to-json-schema.js
|
|
64
|
+
function initializeContext(params) {
|
|
65
|
+
let target = params?.target ?? "draft-2020-12";
|
|
66
|
+
if (target === "draft-4") target = "draft-04";
|
|
67
|
+
if (target === "draft-7") target = "draft-07";
|
|
68
|
+
return {
|
|
69
|
+
processors: params.processors ?? {},
|
|
70
|
+
metadataRegistry: params?.metadata ?? globalRegistry,
|
|
71
|
+
target,
|
|
72
|
+
unrepresentable: params?.unrepresentable ?? "throw",
|
|
73
|
+
override: params?.override ?? (() => {}),
|
|
74
|
+
io: params?.io ?? "output",
|
|
75
|
+
counter: 0,
|
|
76
|
+
seen: /* @__PURE__ */ new Map(),
|
|
77
|
+
cycles: params?.cycles ?? "ref",
|
|
78
|
+
reused: params?.reused ?? "inline",
|
|
79
|
+
external: params?.external ?? void 0
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function process(schema, ctx, _params = {
|
|
83
|
+
path: [],
|
|
84
|
+
schemaPath: []
|
|
85
|
+
}) {
|
|
86
|
+
var _a;
|
|
87
|
+
const def = schema._zod.def;
|
|
88
|
+
const seen = ctx.seen.get(schema);
|
|
89
|
+
if (seen) {
|
|
90
|
+
seen.count++;
|
|
91
|
+
if (_params.schemaPath.includes(schema)) seen.cycle = _params.path;
|
|
92
|
+
return seen.schema;
|
|
93
|
+
}
|
|
94
|
+
const result = {
|
|
95
|
+
schema: {},
|
|
96
|
+
count: 1,
|
|
97
|
+
cycle: void 0,
|
|
98
|
+
path: _params.path
|
|
99
|
+
};
|
|
100
|
+
ctx.seen.set(schema, result);
|
|
101
|
+
const overrideSchema = schema._zod.toJSONSchema?.();
|
|
102
|
+
if (overrideSchema) result.schema = overrideSchema;
|
|
103
|
+
else {
|
|
104
|
+
const params = {
|
|
105
|
+
..._params,
|
|
106
|
+
schemaPath: [..._params.schemaPath, schema],
|
|
107
|
+
path: _params.path
|
|
108
|
+
};
|
|
109
|
+
if (schema._zod.processJSONSchema) schema._zod.processJSONSchema(ctx, result.schema, params);
|
|
110
|
+
else {
|
|
111
|
+
const _json = result.schema;
|
|
112
|
+
const processor = ctx.processors[def.type];
|
|
113
|
+
if (!processor) throw new Error(`[toJSONSchema]: Non-representable type encountered: ${def.type}`);
|
|
114
|
+
processor(schema, ctx, _json, params);
|
|
115
|
+
}
|
|
116
|
+
const parent = schema._zod.parent;
|
|
117
|
+
if (parent) {
|
|
118
|
+
if (!result.ref) result.ref = parent;
|
|
119
|
+
process(parent, ctx, params);
|
|
120
|
+
ctx.seen.get(parent).isParent = true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const meta = ctx.metadataRegistry.get(schema);
|
|
124
|
+
if (meta) Object.assign(result.schema, meta);
|
|
125
|
+
if (ctx.io === "input" && isTransforming(schema)) {
|
|
126
|
+
delete result.schema.examples;
|
|
127
|
+
delete result.schema.default;
|
|
128
|
+
}
|
|
129
|
+
if (ctx.io === "input" && "_prefault" in result.schema) (_a = result.schema).default ?? (_a.default = result.schema._prefault);
|
|
130
|
+
delete result.schema._prefault;
|
|
131
|
+
return ctx.seen.get(schema).schema;
|
|
132
|
+
}
|
|
133
|
+
function extractDefs(ctx, schema) {
|
|
134
|
+
const root = ctx.seen.get(schema);
|
|
135
|
+
if (!root) throw new Error("Unprocessed schema. This is a bug in Zod.");
|
|
136
|
+
const idToSchema = /* @__PURE__ */ new Map();
|
|
137
|
+
for (const entry of ctx.seen.entries()) {
|
|
138
|
+
const id = ctx.metadataRegistry.get(entry[0])?.id;
|
|
139
|
+
if (id) {
|
|
140
|
+
const existing = idToSchema.get(id);
|
|
141
|
+
if (existing && existing !== entry[0]) throw new Error(`Duplicate schema id "${id}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
|
|
142
|
+
idToSchema.set(id, entry[0]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const makeURI = (entry) => {
|
|
146
|
+
const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
|
|
147
|
+
if (ctx.external) {
|
|
148
|
+
const externalId = ctx.external.registry.get(entry[0])?.id;
|
|
149
|
+
const uriGenerator = ctx.external.uri ?? ((id) => id);
|
|
150
|
+
if (externalId) return { ref: uriGenerator(externalId) };
|
|
151
|
+
const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
|
|
152
|
+
entry[1].defId = id;
|
|
153
|
+
return {
|
|
154
|
+
defId: id,
|
|
155
|
+
ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}`
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (entry[1] === root) return { ref: "#" };
|
|
159
|
+
const defUriPrefix = `#/${defsSegment}/`;
|
|
160
|
+
const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`;
|
|
161
|
+
return {
|
|
162
|
+
defId,
|
|
163
|
+
ref: defUriPrefix + defId
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
const extractToDef = (entry) => {
|
|
167
|
+
if (entry[1].schema.$ref) return;
|
|
168
|
+
const seen = entry[1];
|
|
169
|
+
const { ref, defId } = makeURI(entry);
|
|
170
|
+
seen.def = { ...seen.schema };
|
|
171
|
+
if (defId) seen.defId = defId;
|
|
172
|
+
const schema = seen.schema;
|
|
173
|
+
for (const key in schema) delete schema[key];
|
|
174
|
+
schema.$ref = ref;
|
|
175
|
+
};
|
|
176
|
+
if (ctx.cycles === "throw") for (const entry of ctx.seen.entries()) {
|
|
177
|
+
const seen = entry[1];
|
|
178
|
+
if (seen.cycle) throw new Error(`Cycle detected: #/${seen.cycle?.join("/")}/<root>
|
|
179
|
+
|
|
180
|
+
Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`);
|
|
181
|
+
}
|
|
182
|
+
for (const entry of ctx.seen.entries()) {
|
|
183
|
+
const seen = entry[1];
|
|
184
|
+
if (schema === entry[0]) {
|
|
185
|
+
extractToDef(entry);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (ctx.external) {
|
|
189
|
+
const ext = ctx.external.registry.get(entry[0])?.id;
|
|
190
|
+
if (schema !== entry[0] && ext) {
|
|
191
|
+
extractToDef(entry);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (ctx.metadataRegistry.get(entry[0])?.id) {
|
|
196
|
+
extractToDef(entry);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (seen.cycle) {
|
|
200
|
+
extractToDef(entry);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (seen.count > 1) {
|
|
204
|
+
if (ctx.reused === "ref") {
|
|
205
|
+
extractToDef(entry);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function finalize(ctx, schema) {
|
|
212
|
+
const root = ctx.seen.get(schema);
|
|
213
|
+
if (!root) throw new Error("Unprocessed schema. This is a bug in Zod.");
|
|
214
|
+
const flattenRef = (zodSchema) => {
|
|
215
|
+
const seen = ctx.seen.get(zodSchema);
|
|
216
|
+
if (seen.ref === null) return;
|
|
217
|
+
const schema = seen.def ?? seen.schema;
|
|
218
|
+
const _cached = { ...schema };
|
|
219
|
+
const ref = seen.ref;
|
|
220
|
+
seen.ref = null;
|
|
221
|
+
if (ref) {
|
|
222
|
+
flattenRef(ref);
|
|
223
|
+
const refSeen = ctx.seen.get(ref);
|
|
224
|
+
const refSchema = refSeen.schema;
|
|
225
|
+
if (refSchema.$ref && (ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0")) {
|
|
226
|
+
schema.allOf = schema.allOf ?? [];
|
|
227
|
+
schema.allOf.push(refSchema);
|
|
228
|
+
} else Object.assign(schema, refSchema);
|
|
229
|
+
Object.assign(schema, _cached);
|
|
230
|
+
if (zodSchema._zod.parent === ref) for (const key in schema) {
|
|
231
|
+
if (key === "$ref" || key === "allOf") continue;
|
|
232
|
+
if (!(key in _cached)) delete schema[key];
|
|
233
|
+
}
|
|
234
|
+
if (refSchema.$ref && refSeen.def) for (const key in schema) {
|
|
235
|
+
if (key === "$ref" || key === "allOf") continue;
|
|
236
|
+
if (key in refSeen.def && JSON.stringify(schema[key]) === JSON.stringify(refSeen.def[key])) delete schema[key];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const parent = zodSchema._zod.parent;
|
|
240
|
+
if (parent && parent !== ref) {
|
|
241
|
+
flattenRef(parent);
|
|
242
|
+
const parentSeen = ctx.seen.get(parent);
|
|
243
|
+
if (parentSeen?.schema.$ref) {
|
|
244
|
+
schema.$ref = parentSeen.schema.$ref;
|
|
245
|
+
if (parentSeen.def) for (const key in schema) {
|
|
246
|
+
if (key === "$ref" || key === "allOf") continue;
|
|
247
|
+
if (key in parentSeen.def && JSON.stringify(schema[key]) === JSON.stringify(parentSeen.def[key])) delete schema[key];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
ctx.override({
|
|
252
|
+
zodSchema,
|
|
253
|
+
jsonSchema: schema,
|
|
254
|
+
path: seen.path ?? []
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
for (const entry of [...ctx.seen.entries()].reverse()) flattenRef(entry[0]);
|
|
258
|
+
const result = {};
|
|
259
|
+
if (ctx.target === "draft-2020-12") result.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
260
|
+
else if (ctx.target === "draft-07") result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
261
|
+
else if (ctx.target === "draft-04") result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
262
|
+
else if (ctx.target === "openapi-3.0") {}
|
|
263
|
+
if (ctx.external?.uri) {
|
|
264
|
+
const id = ctx.external.registry.get(schema)?.id;
|
|
265
|
+
if (!id) throw new Error("Schema is missing an `id` property");
|
|
266
|
+
result.$id = ctx.external.uri(id);
|
|
267
|
+
}
|
|
268
|
+
Object.assign(result, root.def ?? root.schema);
|
|
269
|
+
const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
|
|
270
|
+
if (rootMetaId !== void 0 && result.id === rootMetaId) delete result.id;
|
|
271
|
+
const defs = ctx.external?.defs ?? {};
|
|
272
|
+
for (const entry of ctx.seen.entries()) {
|
|
273
|
+
const seen = entry[1];
|
|
274
|
+
if (seen.def && seen.defId) {
|
|
275
|
+
if (seen.def.id === seen.defId) delete seen.def.id;
|
|
276
|
+
defs[seen.defId] = seen.def;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (ctx.external) {} else if (Object.keys(defs).length > 0) if (ctx.target === "draft-2020-12") result.$defs = defs;
|
|
280
|
+
else result.definitions = defs;
|
|
281
|
+
try {
|
|
282
|
+
const finalized = JSON.parse(JSON.stringify(result));
|
|
283
|
+
Object.defineProperty(finalized, "~standard", {
|
|
284
|
+
value: {
|
|
285
|
+
...schema["~standard"],
|
|
286
|
+
jsonSchema: {
|
|
287
|
+
input: createStandardJSONSchemaMethod(schema, "input", ctx.processors),
|
|
288
|
+
output: createStandardJSONSchemaMethod(schema, "output", ctx.processors)
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
enumerable: false,
|
|
292
|
+
writable: false
|
|
293
|
+
});
|
|
294
|
+
return finalized;
|
|
295
|
+
} catch (_err) {
|
|
296
|
+
throw new Error("Error converting schema to JSON.");
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function isTransforming(_schema, _ctx) {
|
|
300
|
+
const ctx = _ctx ?? { seen: /* @__PURE__ */ new Set() };
|
|
301
|
+
if (ctx.seen.has(_schema)) return false;
|
|
302
|
+
ctx.seen.add(_schema);
|
|
303
|
+
const def = _schema._zod.def;
|
|
304
|
+
if (def.type === "transform") return true;
|
|
305
|
+
if (def.type === "array") return isTransforming(def.element, ctx);
|
|
306
|
+
if (def.type === "set") return isTransforming(def.valueType, ctx);
|
|
307
|
+
if (def.type === "lazy") return isTransforming(def.getter(), ctx);
|
|
308
|
+
if (def.type === "promise" || def.type === "optional" || def.type === "nonoptional" || def.type === "nullable" || def.type === "readonly" || def.type === "default" || def.type === "prefault") return isTransforming(def.innerType, ctx);
|
|
309
|
+
if (def.type === "intersection") return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);
|
|
310
|
+
if (def.type === "record" || def.type === "map") return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
311
|
+
if (def.type === "pipe") {
|
|
312
|
+
if (_schema._zod.traits.has("$ZodCodec")) return true;
|
|
313
|
+
return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
|
|
314
|
+
}
|
|
315
|
+
if (def.type === "object") {
|
|
316
|
+
for (const key in def.shape) if (isTransforming(def.shape[key], ctx)) return true;
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
if (def.type === "union") {
|
|
320
|
+
for (const option of def.options) if (isTransforming(option, ctx)) return true;
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
if (def.type === "tuple") {
|
|
324
|
+
for (const item of def.items) if (isTransforming(item, ctx)) return true;
|
|
325
|
+
if (def.rest && isTransforming(def.rest, ctx)) return true;
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
|
|
331
|
+
const { libraryOptions, target } = params ?? {};
|
|
332
|
+
const ctx = initializeContext({
|
|
333
|
+
...libraryOptions ?? {},
|
|
334
|
+
target,
|
|
335
|
+
io,
|
|
336
|
+
processors
|
|
337
|
+
});
|
|
338
|
+
process(schema, ctx);
|
|
339
|
+
extractDefs(ctx, schema);
|
|
340
|
+
return finalize(ctx, schema);
|
|
341
|
+
};
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region ../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-processors.js
|
|
344
|
+
const formatMap = {
|
|
345
|
+
guid: "uuid",
|
|
346
|
+
url: "uri",
|
|
347
|
+
datetime: "date-time",
|
|
348
|
+
json_string: "json-string",
|
|
349
|
+
regex: ""
|
|
350
|
+
};
|
|
351
|
+
const stringProcessor = (schema, ctx, _json, _params) => {
|
|
352
|
+
const json = _json;
|
|
353
|
+
json.type = "string";
|
|
354
|
+
const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
|
|
355
|
+
if (typeof minimum === "number") json.minLength = minimum;
|
|
356
|
+
if (typeof maximum === "number") json.maxLength = maximum;
|
|
357
|
+
if (format) {
|
|
358
|
+
json.format = formatMap[format] ?? format;
|
|
359
|
+
if (json.format === "") delete json.format;
|
|
360
|
+
if (format === "time") delete json.format;
|
|
361
|
+
}
|
|
362
|
+
if (contentEncoding) json.contentEncoding = contentEncoding;
|
|
363
|
+
if (patterns && patterns.size > 0) {
|
|
364
|
+
const regexes = [...patterns];
|
|
365
|
+
if (regexes.length === 1) json.pattern = regexes[0].source;
|
|
366
|
+
else if (regexes.length > 1) json.allOf = [...regexes.map((regex) => ({
|
|
367
|
+
...ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0" ? { type: "string" } : {},
|
|
368
|
+
pattern: regex.source
|
|
369
|
+
}))];
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
const numberProcessor = (schema, ctx, _json, _params) => {
|
|
373
|
+
const json = _json;
|
|
374
|
+
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
375
|
+
if (typeof format === "string" && format.includes("int")) json.type = "integer";
|
|
376
|
+
else json.type = "number";
|
|
377
|
+
const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
|
|
378
|
+
const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
|
|
379
|
+
const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
|
|
380
|
+
if (exMin) if (legacy) {
|
|
381
|
+
json.minimum = exclusiveMinimum;
|
|
382
|
+
json.exclusiveMinimum = true;
|
|
383
|
+
} else json.exclusiveMinimum = exclusiveMinimum;
|
|
384
|
+
else if (typeof minimum === "number") json.minimum = minimum;
|
|
385
|
+
if (exMax) if (legacy) {
|
|
386
|
+
json.maximum = exclusiveMaximum;
|
|
387
|
+
json.exclusiveMaximum = true;
|
|
388
|
+
} else json.exclusiveMaximum = exclusiveMaximum;
|
|
389
|
+
else if (typeof maximum === "number") json.maximum = maximum;
|
|
390
|
+
if (typeof multipleOf === "number") json.multipleOf = multipleOf;
|
|
391
|
+
};
|
|
392
|
+
const booleanProcessor = (_schema, _ctx, json, _params) => {
|
|
393
|
+
json.type = "boolean";
|
|
394
|
+
};
|
|
395
|
+
const bigintProcessor = (_schema, ctx, _json, _params) => {
|
|
396
|
+
if (ctx.unrepresentable === "throw") throw new Error("BigInt cannot be represented in JSON Schema");
|
|
397
|
+
};
|
|
398
|
+
const symbolProcessor = (_schema, ctx, _json, _params) => {
|
|
399
|
+
if (ctx.unrepresentable === "throw") throw new Error("Symbols cannot be represented in JSON Schema");
|
|
400
|
+
};
|
|
401
|
+
const nullProcessor = (_schema, ctx, json, _params) => {
|
|
402
|
+
if (ctx.target === "openapi-3.0") {
|
|
403
|
+
json.type = "string";
|
|
404
|
+
json.nullable = true;
|
|
405
|
+
json.enum = [null];
|
|
406
|
+
} else json.type = "null";
|
|
407
|
+
};
|
|
408
|
+
const undefinedProcessor = (_schema, ctx, _json, _params) => {
|
|
409
|
+
if (ctx.unrepresentable === "throw") throw new Error("Undefined cannot be represented in JSON Schema");
|
|
410
|
+
};
|
|
411
|
+
const voidProcessor = (_schema, ctx, _json, _params) => {
|
|
412
|
+
if (ctx.unrepresentable === "throw") throw new Error("Void cannot be represented in JSON Schema");
|
|
413
|
+
};
|
|
414
|
+
const neverProcessor = (_schema, _ctx, json, _params) => {
|
|
415
|
+
json.not = {};
|
|
416
|
+
};
|
|
417
|
+
const anyProcessor = (_schema, _ctx, _json, _params) => {};
|
|
418
|
+
const unknownProcessor = (_schema, _ctx, _json, _params) => {};
|
|
419
|
+
const dateProcessor = (_schema, ctx, _json, _params) => {
|
|
420
|
+
if (ctx.unrepresentable === "throw") throw new Error("Date cannot be represented in JSON Schema");
|
|
421
|
+
};
|
|
422
|
+
const enumProcessor = (schema, _ctx, json, _params) => {
|
|
423
|
+
const def = schema._zod.def;
|
|
424
|
+
const values = getEnumValues(def.entries);
|
|
425
|
+
if (values.every((v) => typeof v === "number")) json.type = "number";
|
|
426
|
+
if (values.every((v) => typeof v === "string")) json.type = "string";
|
|
427
|
+
json.enum = values;
|
|
428
|
+
};
|
|
429
|
+
const literalProcessor = (schema, ctx, json, _params) => {
|
|
430
|
+
const def = schema._zod.def;
|
|
431
|
+
const vals = [];
|
|
432
|
+
for (const val of def.values) if (val === void 0) {
|
|
433
|
+
if (ctx.unrepresentable === "throw") throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
434
|
+
} else if (typeof val === "bigint") if (ctx.unrepresentable === "throw") throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
435
|
+
else vals.push(Number(val));
|
|
436
|
+
else vals.push(val);
|
|
437
|
+
if (vals.length === 0) {} else if (vals.length === 1) {
|
|
438
|
+
const val = vals[0];
|
|
439
|
+
json.type = val === null ? "null" : typeof val;
|
|
440
|
+
if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") json.enum = [val];
|
|
441
|
+
else json.const = val;
|
|
442
|
+
} else {
|
|
443
|
+
if (vals.every((v) => typeof v === "number")) json.type = "number";
|
|
444
|
+
if (vals.every((v) => typeof v === "string")) json.type = "string";
|
|
445
|
+
if (vals.every((v) => typeof v === "boolean")) json.type = "boolean";
|
|
446
|
+
if (vals.every((v) => v === null)) json.type = "null";
|
|
447
|
+
json.enum = vals;
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
const nanProcessor = (_schema, ctx, _json, _params) => {
|
|
451
|
+
if (ctx.unrepresentable === "throw") throw new Error("NaN cannot be represented in JSON Schema");
|
|
452
|
+
};
|
|
453
|
+
const templateLiteralProcessor = (schema, _ctx, json, _params) => {
|
|
454
|
+
const _json = json;
|
|
455
|
+
const pattern = schema._zod.pattern;
|
|
456
|
+
if (!pattern) throw new Error("Pattern not found in template literal");
|
|
457
|
+
_json.type = "string";
|
|
458
|
+
_json.pattern = pattern.source;
|
|
459
|
+
};
|
|
460
|
+
const fileProcessor = (schema, _ctx, json, _params) => {
|
|
461
|
+
const _json = json;
|
|
462
|
+
const file = {
|
|
463
|
+
type: "string",
|
|
464
|
+
format: "binary",
|
|
465
|
+
contentEncoding: "binary"
|
|
466
|
+
};
|
|
467
|
+
const { minimum, maximum, mime } = schema._zod.bag;
|
|
468
|
+
if (minimum !== void 0) file.minLength = minimum;
|
|
469
|
+
if (maximum !== void 0) file.maxLength = maximum;
|
|
470
|
+
if (mime) if (mime.length === 1) {
|
|
471
|
+
file.contentMediaType = mime[0];
|
|
472
|
+
Object.assign(_json, file);
|
|
473
|
+
} else {
|
|
474
|
+
Object.assign(_json, file);
|
|
475
|
+
_json.anyOf = mime.map((m) => ({ contentMediaType: m }));
|
|
476
|
+
}
|
|
477
|
+
else Object.assign(_json, file);
|
|
478
|
+
};
|
|
479
|
+
const successProcessor = (_schema, _ctx, json, _params) => {
|
|
480
|
+
json.type = "boolean";
|
|
481
|
+
};
|
|
482
|
+
const customProcessor = (_schema, ctx, _json, _params) => {
|
|
483
|
+
if (ctx.unrepresentable === "throw") throw new Error("Custom types cannot be represented in JSON Schema");
|
|
484
|
+
};
|
|
485
|
+
const functionProcessor = (_schema, ctx, _json, _params) => {
|
|
486
|
+
if (ctx.unrepresentable === "throw") throw new Error("Function types cannot be represented in JSON Schema");
|
|
487
|
+
};
|
|
488
|
+
const transformProcessor = (_schema, ctx, _json, _params) => {
|
|
489
|
+
if (ctx.unrepresentable === "throw") throw new Error("Transforms cannot be represented in JSON Schema");
|
|
490
|
+
};
|
|
491
|
+
const mapProcessor = (_schema, ctx, _json, _params) => {
|
|
492
|
+
if (ctx.unrepresentable === "throw") throw new Error("Map cannot be represented in JSON Schema");
|
|
493
|
+
};
|
|
494
|
+
const setProcessor = (_schema, ctx, _json, _params) => {
|
|
495
|
+
if (ctx.unrepresentable === "throw") throw new Error("Set cannot be represented in JSON Schema");
|
|
496
|
+
};
|
|
497
|
+
const arrayProcessor = (schema, ctx, _json, params) => {
|
|
498
|
+
const json = _json;
|
|
499
|
+
const def = schema._zod.def;
|
|
500
|
+
const { minimum, maximum } = schema._zod.bag;
|
|
501
|
+
if (typeof minimum === "number") json.minItems = minimum;
|
|
502
|
+
if (typeof maximum === "number") json.maxItems = maximum;
|
|
503
|
+
json.type = "array";
|
|
504
|
+
json.items = process(def.element, ctx, {
|
|
505
|
+
...params,
|
|
506
|
+
path: [...params.path, "items"]
|
|
507
|
+
});
|
|
508
|
+
};
|
|
509
|
+
const objectProcessor = (schema, ctx, _json, params) => {
|
|
510
|
+
const json = _json;
|
|
511
|
+
const def = schema._zod.def;
|
|
512
|
+
json.type = "object";
|
|
513
|
+
json.properties = {};
|
|
514
|
+
const shape = def.shape;
|
|
515
|
+
for (const key in shape) json.properties[key] = process(shape[key], ctx, {
|
|
516
|
+
...params,
|
|
517
|
+
path: [
|
|
518
|
+
...params.path,
|
|
519
|
+
"properties",
|
|
520
|
+
key
|
|
521
|
+
]
|
|
522
|
+
});
|
|
523
|
+
const allKeys = new Set(Object.keys(shape));
|
|
524
|
+
const requiredKeys = new Set([...allKeys].filter((key) => {
|
|
525
|
+
const v = def.shape[key]._zod;
|
|
526
|
+
if (ctx.io === "input") return v.optin === void 0;
|
|
527
|
+
else return v.optout === void 0;
|
|
528
|
+
}));
|
|
529
|
+
if (requiredKeys.size > 0) json.required = Array.from(requiredKeys);
|
|
530
|
+
if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
|
|
531
|
+
else if (!def.catchall) {
|
|
532
|
+
if (ctx.io === "output") json.additionalProperties = false;
|
|
533
|
+
} else if (def.catchall) json.additionalProperties = process(def.catchall, ctx, {
|
|
534
|
+
...params,
|
|
535
|
+
path: [...params.path, "additionalProperties"]
|
|
536
|
+
});
|
|
537
|
+
};
|
|
538
|
+
const unionProcessor = (schema, ctx, json, params) => {
|
|
539
|
+
const def = schema._zod.def;
|
|
540
|
+
const isExclusive = def.inclusive === false;
|
|
541
|
+
const options = def.options.map((x, i) => process(x, ctx, {
|
|
542
|
+
...params,
|
|
543
|
+
path: [
|
|
544
|
+
...params.path,
|
|
545
|
+
isExclusive ? "oneOf" : "anyOf",
|
|
546
|
+
i
|
|
547
|
+
]
|
|
548
|
+
}));
|
|
549
|
+
if (isExclusive) json.oneOf = options;
|
|
550
|
+
else json.anyOf = options;
|
|
551
|
+
};
|
|
552
|
+
const intersectionProcessor = (schema, ctx, json, params) => {
|
|
553
|
+
const def = schema._zod.def;
|
|
554
|
+
const a = process(def.left, ctx, {
|
|
555
|
+
...params,
|
|
556
|
+
path: [
|
|
557
|
+
...params.path,
|
|
558
|
+
"allOf",
|
|
559
|
+
0
|
|
560
|
+
]
|
|
561
|
+
});
|
|
562
|
+
const b = process(def.right, ctx, {
|
|
563
|
+
...params,
|
|
564
|
+
path: [
|
|
565
|
+
...params.path,
|
|
566
|
+
"allOf",
|
|
567
|
+
1
|
|
568
|
+
]
|
|
569
|
+
});
|
|
570
|
+
const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
|
|
571
|
+
json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
|
|
572
|
+
};
|
|
573
|
+
const tupleProcessor = (schema, ctx, _json, params) => {
|
|
574
|
+
const json = _json;
|
|
575
|
+
const def = schema._zod.def;
|
|
576
|
+
json.type = "array";
|
|
577
|
+
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
578
|
+
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
579
|
+
const prefixItems = def.items.map((x, i) => process(x, ctx, {
|
|
580
|
+
...params,
|
|
581
|
+
path: [
|
|
582
|
+
...params.path,
|
|
583
|
+
prefixPath,
|
|
584
|
+
i
|
|
585
|
+
]
|
|
586
|
+
}));
|
|
587
|
+
const rest = def.rest ? process(def.rest, ctx, {
|
|
588
|
+
...params,
|
|
589
|
+
path: [
|
|
590
|
+
...params.path,
|
|
591
|
+
restPath,
|
|
592
|
+
...ctx.target === "openapi-3.0" ? [def.items.length] : []
|
|
593
|
+
]
|
|
594
|
+
}) : null;
|
|
595
|
+
if (ctx.target === "draft-2020-12") {
|
|
596
|
+
json.prefixItems = prefixItems;
|
|
597
|
+
if (rest) json.items = rest;
|
|
598
|
+
} else if (ctx.target === "openapi-3.0") {
|
|
599
|
+
json.items = { anyOf: prefixItems };
|
|
600
|
+
if (rest) json.items.anyOf.push(rest);
|
|
601
|
+
json.minItems = prefixItems.length;
|
|
602
|
+
if (!rest) json.maxItems = prefixItems.length;
|
|
603
|
+
} else {
|
|
604
|
+
json.items = prefixItems;
|
|
605
|
+
if (rest) json.additionalItems = rest;
|
|
606
|
+
}
|
|
607
|
+
const { minimum, maximum } = schema._zod.bag;
|
|
608
|
+
if (typeof minimum === "number") json.minItems = minimum;
|
|
609
|
+
if (typeof maximum === "number") json.maxItems = maximum;
|
|
610
|
+
};
|
|
611
|
+
const recordProcessor = (schema, ctx, _json, params) => {
|
|
612
|
+
const json = _json;
|
|
613
|
+
const def = schema._zod.def;
|
|
614
|
+
json.type = "object";
|
|
615
|
+
const keyType = def.keyType;
|
|
616
|
+
const patterns = keyType._zod.bag?.patterns;
|
|
617
|
+
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
618
|
+
const valueSchema = process(def.valueType, ctx, {
|
|
619
|
+
...params,
|
|
620
|
+
path: [
|
|
621
|
+
...params.path,
|
|
622
|
+
"patternProperties",
|
|
623
|
+
"*"
|
|
624
|
+
]
|
|
625
|
+
});
|
|
626
|
+
json.patternProperties = {};
|
|
627
|
+
for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
|
|
628
|
+
} else {
|
|
629
|
+
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process(def.keyType, ctx, {
|
|
630
|
+
...params,
|
|
631
|
+
path: [...params.path, "propertyNames"]
|
|
632
|
+
});
|
|
633
|
+
json.additionalProperties = process(def.valueType, ctx, {
|
|
634
|
+
...params,
|
|
635
|
+
path: [...params.path, "additionalProperties"]
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
const keyValues = keyType._zod.values;
|
|
639
|
+
if (keyValues) {
|
|
640
|
+
const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
|
|
641
|
+
if (validKeyValues.length > 0) json.required = validKeyValues;
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
const nullableProcessor = (schema, ctx, json, params) => {
|
|
645
|
+
const def = schema._zod.def;
|
|
646
|
+
const inner = process(def.innerType, ctx, params);
|
|
647
|
+
const seen = ctx.seen.get(schema);
|
|
648
|
+
if (ctx.target === "openapi-3.0") {
|
|
649
|
+
seen.ref = def.innerType;
|
|
650
|
+
json.nullable = true;
|
|
651
|
+
} else json.anyOf = [inner, { type: "null" }];
|
|
652
|
+
};
|
|
653
|
+
const nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
654
|
+
const def = schema._zod.def;
|
|
655
|
+
process(def.innerType, ctx, params);
|
|
656
|
+
const seen = ctx.seen.get(schema);
|
|
657
|
+
seen.ref = def.innerType;
|
|
658
|
+
};
|
|
659
|
+
const defaultProcessor = (schema, ctx, json, params) => {
|
|
660
|
+
const def = schema._zod.def;
|
|
661
|
+
process(def.innerType, ctx, params);
|
|
662
|
+
const seen = ctx.seen.get(schema);
|
|
663
|
+
seen.ref = def.innerType;
|
|
664
|
+
json.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
665
|
+
};
|
|
666
|
+
const prefaultProcessor = (schema, ctx, json, params) => {
|
|
667
|
+
const def = schema._zod.def;
|
|
668
|
+
process(def.innerType, ctx, params);
|
|
669
|
+
const seen = ctx.seen.get(schema);
|
|
670
|
+
seen.ref = def.innerType;
|
|
671
|
+
if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
|
|
672
|
+
};
|
|
673
|
+
const catchProcessor = (schema, ctx, json, params) => {
|
|
674
|
+
const def = schema._zod.def;
|
|
675
|
+
process(def.innerType, ctx, params);
|
|
676
|
+
const seen = ctx.seen.get(schema);
|
|
677
|
+
seen.ref = def.innerType;
|
|
678
|
+
let catchValue;
|
|
679
|
+
try {
|
|
680
|
+
catchValue = def.catchValue(void 0);
|
|
681
|
+
} catch {
|
|
682
|
+
throw new Error("Dynamic catch values are not supported in JSON Schema");
|
|
683
|
+
}
|
|
684
|
+
json.default = catchValue;
|
|
685
|
+
};
|
|
686
|
+
const pipeProcessor = (schema, ctx, _json, params) => {
|
|
687
|
+
const def = schema._zod.def;
|
|
688
|
+
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
689
|
+
const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
|
|
690
|
+
process(innerType, ctx, params);
|
|
691
|
+
const seen = ctx.seen.get(schema);
|
|
692
|
+
seen.ref = innerType;
|
|
693
|
+
};
|
|
694
|
+
const readonlyProcessor = (schema, ctx, json, params) => {
|
|
695
|
+
const def = schema._zod.def;
|
|
696
|
+
process(def.innerType, ctx, params);
|
|
697
|
+
const seen = ctx.seen.get(schema);
|
|
698
|
+
seen.ref = def.innerType;
|
|
699
|
+
json.readOnly = true;
|
|
700
|
+
};
|
|
701
|
+
const promiseProcessor = (schema, ctx, _json, params) => {
|
|
702
|
+
const def = schema._zod.def;
|
|
703
|
+
process(def.innerType, ctx, params);
|
|
704
|
+
const seen = ctx.seen.get(schema);
|
|
705
|
+
seen.ref = def.innerType;
|
|
706
|
+
};
|
|
707
|
+
const optionalProcessor = (schema, ctx, _json, params) => {
|
|
708
|
+
const def = schema._zod.def;
|
|
709
|
+
process(def.innerType, ctx, params);
|
|
710
|
+
const seen = ctx.seen.get(schema);
|
|
711
|
+
seen.ref = def.innerType;
|
|
712
|
+
};
|
|
713
|
+
const lazyProcessor = (schema, ctx, _json, params) => {
|
|
714
|
+
const innerType = schema._zod.innerType;
|
|
715
|
+
process(innerType, ctx, params);
|
|
716
|
+
const seen = ctx.seen.get(schema);
|
|
717
|
+
seen.ref = innerType;
|
|
718
|
+
};
|
|
719
|
+
const allProcessors = {
|
|
720
|
+
string: stringProcessor,
|
|
721
|
+
number: numberProcessor,
|
|
722
|
+
boolean: booleanProcessor,
|
|
723
|
+
bigint: bigintProcessor,
|
|
724
|
+
symbol: symbolProcessor,
|
|
725
|
+
null: nullProcessor,
|
|
726
|
+
undefined: undefinedProcessor,
|
|
727
|
+
void: voidProcessor,
|
|
728
|
+
never: neverProcessor,
|
|
729
|
+
any: anyProcessor,
|
|
730
|
+
unknown: unknownProcessor,
|
|
731
|
+
date: dateProcessor,
|
|
732
|
+
enum: enumProcessor,
|
|
733
|
+
literal: literalProcessor,
|
|
734
|
+
nan: nanProcessor,
|
|
735
|
+
template_literal: templateLiteralProcessor,
|
|
736
|
+
file: fileProcessor,
|
|
737
|
+
success: successProcessor,
|
|
738
|
+
custom: customProcessor,
|
|
739
|
+
function: functionProcessor,
|
|
740
|
+
transform: transformProcessor,
|
|
741
|
+
map: mapProcessor,
|
|
742
|
+
set: setProcessor,
|
|
743
|
+
array: arrayProcessor,
|
|
744
|
+
object: objectProcessor,
|
|
745
|
+
union: unionProcessor,
|
|
746
|
+
intersection: intersectionProcessor,
|
|
747
|
+
tuple: tupleProcessor,
|
|
748
|
+
record: recordProcessor,
|
|
749
|
+
nullable: nullableProcessor,
|
|
750
|
+
nonoptional: nonoptionalProcessor,
|
|
751
|
+
default: defaultProcessor,
|
|
752
|
+
prefault: prefaultProcessor,
|
|
753
|
+
catch: catchProcessor,
|
|
754
|
+
pipe: pipeProcessor,
|
|
755
|
+
readonly: readonlyProcessor,
|
|
756
|
+
promise: promiseProcessor,
|
|
757
|
+
optional: optionalProcessor,
|
|
758
|
+
lazy: lazyProcessor
|
|
759
|
+
};
|
|
760
|
+
function toJSONSchema(input, params) {
|
|
761
|
+
if ("_idmap" in input) {
|
|
762
|
+
const registry = input;
|
|
763
|
+
const ctx = initializeContext({
|
|
764
|
+
...params,
|
|
765
|
+
processors: allProcessors
|
|
766
|
+
});
|
|
767
|
+
const defs = {};
|
|
768
|
+
for (const entry of registry._idmap.entries()) {
|
|
769
|
+
const [_, schema] = entry;
|
|
770
|
+
process(schema, ctx);
|
|
771
|
+
}
|
|
772
|
+
const schemas = {};
|
|
773
|
+
ctx.external = {
|
|
774
|
+
registry,
|
|
775
|
+
uri: params?.uri,
|
|
776
|
+
defs
|
|
777
|
+
};
|
|
778
|
+
for (const entry of registry._idmap.entries()) {
|
|
779
|
+
const [key, schema] = entry;
|
|
780
|
+
extractDefs(ctx, schema);
|
|
781
|
+
schemas[key] = finalize(ctx, schema);
|
|
782
|
+
}
|
|
783
|
+
if (Object.keys(defs).length > 0) schemas.__shared = { [ctx.target === "draft-2020-12" ? "$defs" : "definitions"]: defs };
|
|
784
|
+
return { schemas };
|
|
785
|
+
}
|
|
786
|
+
const ctx = initializeContext({
|
|
787
|
+
...params,
|
|
788
|
+
processors: allProcessors
|
|
789
|
+
});
|
|
790
|
+
process(input, ctx);
|
|
791
|
+
extractDefs(ctx, input);
|
|
792
|
+
return finalize(ctx, input);
|
|
793
|
+
}
|
|
794
|
+
//#endregion
|
|
795
|
+
//#region lib/types/service.js
|
|
796
|
+
/**
|
|
797
|
+
* Runtime registry for generated Typert reflection, Remote invocations, and
|
|
798
|
+
* dependency-inverted lookup/Context providers. It performs no TypeScript
|
|
799
|
+
* analysis or schema generation.
|
|
800
|
+
* @module @deepseek-ai/dsh-typert-registry
|
|
801
|
+
*/
|
|
802
|
+
/**
|
|
803
|
+
* Compose the global key of one generated schema.
|
|
804
|
+
* @param packageName - contributing npm package.
|
|
805
|
+
* @param name - schema export name.
|
|
806
|
+
* @returns `<package>#<name>`.
|
|
807
|
+
*/
|
|
808
|
+
function typertKey(packageName, name) {
|
|
809
|
+
return `${packageName}#${name}`;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Compose the identity of one package-face model.
|
|
813
|
+
* @param packageName - contributing npm package.
|
|
814
|
+
* @param face - independently compiled face.
|
|
815
|
+
* @returns `<package>#<face>`.
|
|
816
|
+
*/
|
|
817
|
+
function typertPackageKey(packageName, face) {
|
|
818
|
+
return `${packageName}#${face}`;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Compose the endpoint key used by local and Remote invocation registries.
|
|
822
|
+
* @param descriptor - invocation whose namespace and method form the endpoint.
|
|
823
|
+
* @returns `<namespace>/<method>`.
|
|
824
|
+
*/
|
|
825
|
+
function typertEndpoint(descriptor) {
|
|
826
|
+
return `${descriptor.namespace}/${descriptor.method}`;
|
|
827
|
+
}
|
|
828
|
+
var ChangeSource = class {
|
|
829
|
+
report;
|
|
830
|
+
listeners = /* @__PURE__ */ new Set();
|
|
831
|
+
constructor(report) {
|
|
832
|
+
this.report = report;
|
|
833
|
+
}
|
|
834
|
+
subscribe(ctx, listener) {
|
|
835
|
+
const { listeners } = this;
|
|
836
|
+
return ctx.effect(function* () {
|
|
837
|
+
listeners.add(listener);
|
|
838
|
+
yield () => {
|
|
839
|
+
listeners.delete(listener);
|
|
840
|
+
};
|
|
841
|
+
}, "typert registry subscription");
|
|
842
|
+
}
|
|
843
|
+
emit(change) {
|
|
844
|
+
for (const listener of [...this.listeners]) try {
|
|
845
|
+
listener(change);
|
|
846
|
+
} catch (error) {
|
|
847
|
+
this.report(change, error);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
var DescriptorStore = class {
|
|
852
|
+
kind;
|
|
853
|
+
entries = /* @__PURE__ */ new Map();
|
|
854
|
+
ids = /* @__PURE__ */ new Map();
|
|
855
|
+
history = /* @__PURE__ */ new Set();
|
|
856
|
+
changes;
|
|
857
|
+
constructor(kind, report) {
|
|
858
|
+
this.kind = kind;
|
|
859
|
+
this.changes = new ChangeSource(report);
|
|
860
|
+
}
|
|
861
|
+
validate(descriptors) {
|
|
862
|
+
const endpoints = /* @__PURE__ */ new Set();
|
|
863
|
+
const ids = /* @__PURE__ */ new Set();
|
|
864
|
+
for (const descriptor of descriptors) {
|
|
865
|
+
validateInvocation(descriptor);
|
|
866
|
+
const endpoint = typertEndpoint(descriptor);
|
|
867
|
+
if (endpoints.has(endpoint) || this.entries.has(endpoint)) throw new Error(`typert: ${this.kind} endpoint "${endpoint}" is already registered`);
|
|
868
|
+
if (ids.has(descriptor.id) || this.ids.has(descriptor.id)) throw new Error(`typert: ${this.kind} invocation id "${descriptor.id}" is already registered`);
|
|
869
|
+
endpoints.add(endpoint);
|
|
870
|
+
ids.add(descriptor.id);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
commit(owner, descriptors) {
|
|
874
|
+
for (const descriptor of descriptors) {
|
|
875
|
+
const entry = {
|
|
876
|
+
descriptor,
|
|
877
|
+
owner
|
|
878
|
+
};
|
|
879
|
+
const endpoint = typertEndpoint(descriptor);
|
|
880
|
+
this.entries.set(endpoint, entry);
|
|
881
|
+
this.ids.set(descriptor.id, entry);
|
|
882
|
+
this.history.add(endpoint);
|
|
883
|
+
}
|
|
884
|
+
for (const descriptor of descriptors) this.changes.emit({
|
|
885
|
+
kind: this.kind,
|
|
886
|
+
key: typertEndpoint(descriptor)
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
withdraw(owner, descriptors) {
|
|
890
|
+
const removed = [];
|
|
891
|
+
for (const descriptor of descriptors) {
|
|
892
|
+
const endpoint = typertEndpoint(descriptor);
|
|
893
|
+
const entry = this.entries.get(endpoint);
|
|
894
|
+
/* v8 ignore next -- duplicate registration is rejected, so no later owner can replace this entry before its effect disposes. */
|
|
895
|
+
if (entry?.owner !== owner) continue;
|
|
896
|
+
this.entries.delete(endpoint);
|
|
897
|
+
/* v8 ignore next -- ids and endpoints are committed and withdrawn together under the same unique owner. */
|
|
898
|
+
if (this.ids.get(descriptor.id) === entry) this.ids.delete(descriptor.id);
|
|
899
|
+
removed.push(endpoint);
|
|
900
|
+
}
|
|
901
|
+
for (const endpoint of removed) this.changes.emit({
|
|
902
|
+
kind: this.kind,
|
|
903
|
+
key: endpoint
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
get(endpoint) {
|
|
907
|
+
return this.entries.get(endpoint)?.descriptor;
|
|
908
|
+
}
|
|
909
|
+
hasSeen(endpoint) {
|
|
910
|
+
return this.history.has(endpoint);
|
|
911
|
+
}
|
|
912
|
+
list() {
|
|
913
|
+
return [...this.entries.values()].map((entry) => entry.descriptor);
|
|
914
|
+
}
|
|
915
|
+
subscribe(ctx, listener) {
|
|
916
|
+
return this.changes.subscribe(ctx, listener);
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
var RemoteStore = class {
|
|
920
|
+
descriptors;
|
|
921
|
+
packages = /* @__PURE__ */ new Map();
|
|
922
|
+
constructor(descriptors) {
|
|
923
|
+
this.descriptors = descriptors;
|
|
924
|
+
}
|
|
925
|
+
view(ctx) {
|
|
926
|
+
return {
|
|
927
|
+
register: (contribution) => this.register(ctx, contribution),
|
|
928
|
+
get: (endpoint) => this.descriptors.get(endpoint),
|
|
929
|
+
list: () => this.descriptors.list(),
|
|
930
|
+
subscribe: (listener) => this.descriptors.subscribe(ctx, listener)
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
register(ctx, contribution) {
|
|
934
|
+
validateSegment("Remote package name", contribution.package);
|
|
935
|
+
if (this.packages.has(contribution.package)) throw new Error(`typert: Remote package "${contribution.package}" is already registered`);
|
|
936
|
+
this.descriptors.validate(contribution.descriptors);
|
|
937
|
+
const owner = {};
|
|
938
|
+
const { packages, descriptors } = this;
|
|
939
|
+
return ctx.effect(function* () {
|
|
940
|
+
packages.set(contribution.package, owner);
|
|
941
|
+
descriptors.commit(owner, contribution.descriptors);
|
|
942
|
+
yield () => {
|
|
943
|
+
/* v8 ignore else -- duplicate package registration is rejected, so this effect remains the package's unique owner. */
|
|
944
|
+
if (packages.get(contribution.package) === owner) packages.delete(contribution.package);
|
|
945
|
+
descriptors.withdraw(owner, contribution.descriptors);
|
|
946
|
+
};
|
|
947
|
+
}, `typert.remotes.register(${JSON.stringify(contribution.package)})`);
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
var LookupStore = class {
|
|
951
|
+
providers = /* @__PURE__ */ new Map();
|
|
952
|
+
resolvers = /* @__PURE__ */ new Map();
|
|
953
|
+
definitions = /* @__PURE__ */ new Map();
|
|
954
|
+
changes;
|
|
955
|
+
constructor(report) {
|
|
956
|
+
this.changes = new ChangeSource(report);
|
|
957
|
+
}
|
|
958
|
+
view(ctx) {
|
|
959
|
+
return {
|
|
960
|
+
register: (key, provider) => this.register(ctx, key, provider),
|
|
961
|
+
configure: (key, resolver) => this.configure(ctx, key, resolver),
|
|
962
|
+
get: (key) => this.get(key),
|
|
963
|
+
definitions: () => [...this.definitions.values()],
|
|
964
|
+
keys: () => [...this.providers.keys()],
|
|
965
|
+
subscribe: (listener) => this.changes.subscribe(ctx, listener)
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
get(key) {
|
|
969
|
+
const provider = this.providers.get(key)?.provider;
|
|
970
|
+
if (provider === void 0) return void 0;
|
|
971
|
+
const resolver = this.resolvers.get(key)?.provider;
|
|
972
|
+
if (resolver === void 0) return provider;
|
|
973
|
+
return {
|
|
974
|
+
parameter: provider.parameter,
|
|
975
|
+
wire: provider.wire,
|
|
976
|
+
hostTypeSymbol: provider.hostTypeSymbol,
|
|
977
|
+
wireTypeSymbol: provider.wireTypeSymbol,
|
|
978
|
+
resolve: (id) => resolver.resolve(id)
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
configure(ctx, key, resolver) {
|
|
982
|
+
validateSegment("lookup key", key);
|
|
983
|
+
if (this.resolvers.has(key)) throw new Error(`typert: lookup "${key}" resolver is already configured`);
|
|
984
|
+
const entry = {
|
|
985
|
+
provider: { resolve: async (id) => resolver(id) },
|
|
986
|
+
owner: {}
|
|
987
|
+
};
|
|
988
|
+
const { resolvers, changes } = this;
|
|
989
|
+
return ctx.effect(function* () {
|
|
990
|
+
resolvers.set(key, entry);
|
|
991
|
+
changes.emit({
|
|
992
|
+
kind: "lookup",
|
|
993
|
+
key
|
|
994
|
+
});
|
|
995
|
+
yield () => {
|
|
996
|
+
/* v8 ignore next -- duplicate configuration is rejected, so this effect remains the key's unique owner. */
|
|
997
|
+
if (resolvers.get(key) !== entry) return;
|
|
998
|
+
resolvers.delete(key);
|
|
999
|
+
changes.emit({
|
|
1000
|
+
kind: "lookup",
|
|
1001
|
+
key
|
|
1002
|
+
});
|
|
1003
|
+
};
|
|
1004
|
+
}, `typert.lookups.configure(${JSON.stringify(key)})`);
|
|
1005
|
+
}
|
|
1006
|
+
register(ctx, key, provider) {
|
|
1007
|
+
validateSegment("lookup key", key);
|
|
1008
|
+
validateSegment("lookup parameter", provider.parameter);
|
|
1009
|
+
validateWireName("lookup wire field", provider.wire);
|
|
1010
|
+
validateNonempty("lookup Host type symbol", provider.hostTypeSymbol);
|
|
1011
|
+
validateNonempty("lookup wire type symbol", provider.wireTypeSymbol);
|
|
1012
|
+
if (this.providers.has(key)) throw new Error(`typert: lookup "${key}" is already registered`);
|
|
1013
|
+
const definition = {
|
|
1014
|
+
key,
|
|
1015
|
+
parameter: provider.parameter,
|
|
1016
|
+
wire: provider.wire,
|
|
1017
|
+
hostTypeSymbol: provider.hostTypeSymbol,
|
|
1018
|
+
wireTypeSymbol: provider.wireTypeSymbol
|
|
1019
|
+
};
|
|
1020
|
+
const known = this.definitions.get(key);
|
|
1021
|
+
if (known !== void 0 && !lookupDefinitionEquals(known, definition)) throw new Error(`typert: lookup "${key}" changed its wire declaration during this registry lifetime`);
|
|
1022
|
+
const entry = {
|
|
1023
|
+
provider,
|
|
1024
|
+
owner: {}
|
|
1025
|
+
};
|
|
1026
|
+
const { definitions, providers, changes } = this;
|
|
1027
|
+
return ctx.effect(function* () {
|
|
1028
|
+
definitions.set(key, definition);
|
|
1029
|
+
providers.set(key, entry);
|
|
1030
|
+
changes.emit({
|
|
1031
|
+
kind: "lookup",
|
|
1032
|
+
key
|
|
1033
|
+
});
|
|
1034
|
+
yield () => {
|
|
1035
|
+
/* v8 ignore next -- duplicate registration is rejected, so this effect remains the key's unique owner. */
|
|
1036
|
+
if (providers.get(key) !== entry) return;
|
|
1037
|
+
providers.delete(key);
|
|
1038
|
+
changes.emit({
|
|
1039
|
+
kind: "lookup",
|
|
1040
|
+
key
|
|
1041
|
+
});
|
|
1042
|
+
};
|
|
1043
|
+
}, `typert.lookups.register(${JSON.stringify(key)})`);
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
function lookupDefinitionEquals(left, right) {
|
|
1047
|
+
return left.parameter === right.parameter && left.wire === right.wire && left.hostTypeSymbol === right.hostTypeSymbol && left.wireTypeSymbol === right.wireTypeSymbol;
|
|
1048
|
+
}
|
|
1049
|
+
var ContextStore = class {
|
|
1050
|
+
hosts = /* @__PURE__ */ new Map();
|
|
1051
|
+
hostResolvers = /* @__PURE__ */ new Map();
|
|
1052
|
+
clients = /* @__PURE__ */ new Map();
|
|
1053
|
+
changes;
|
|
1054
|
+
constructor(report) {
|
|
1055
|
+
this.changes = new ChangeSource(report);
|
|
1056
|
+
}
|
|
1057
|
+
view(ctx) {
|
|
1058
|
+
return {
|
|
1059
|
+
registerHost: (key, provider) => this.registerHost(ctx, key, provider),
|
|
1060
|
+
configureHost: (key, resolver) => this.configureHost(ctx, key, resolver),
|
|
1061
|
+
registerClient: (key, binder) => this.registerClient(ctx, key, binder),
|
|
1062
|
+
getHost: (key) => this.getHost(key),
|
|
1063
|
+
getClient: (key) => this.clients.get(key)?.provider,
|
|
1064
|
+
subscribe: (listener) => this.changes.subscribe(ctx, listener)
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
getHost(key) {
|
|
1068
|
+
const provider = this.hosts.get(key)?.provider;
|
|
1069
|
+
if (provider === void 0) return void 0;
|
|
1070
|
+
const resolver = this.hostResolvers.get(key)?.provider;
|
|
1071
|
+
if (resolver === void 0) return provider;
|
|
1072
|
+
return {
|
|
1073
|
+
wire: provider.wire,
|
|
1074
|
+
wireTypeSymbol: provider.wireTypeSymbol,
|
|
1075
|
+
resolve: (id) => resolver.resolve(id)
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
configureHost(ctx, key, resolver) {
|
|
1079
|
+
validateSegment("Context key", key);
|
|
1080
|
+
if (this.hostResolvers.has(key)) throw new Error(`typert: host-context "${key}" resolver is already configured`);
|
|
1081
|
+
const entry = {
|
|
1082
|
+
provider: { resolve: async (id) => resolver(id) },
|
|
1083
|
+
owner: {}
|
|
1084
|
+
};
|
|
1085
|
+
const { hostResolvers, changes } = this;
|
|
1086
|
+
return ctx.effect(function* () {
|
|
1087
|
+
hostResolvers.set(key, entry);
|
|
1088
|
+
changes.emit({
|
|
1089
|
+
kind: "host-context",
|
|
1090
|
+
key
|
|
1091
|
+
});
|
|
1092
|
+
yield () => {
|
|
1093
|
+
/* v8 ignore next -- duplicate configuration is rejected, so this effect remains the key's unique owner. */
|
|
1094
|
+
if (hostResolvers.get(key) !== entry) return;
|
|
1095
|
+
hostResolvers.delete(key);
|
|
1096
|
+
changes.emit({
|
|
1097
|
+
kind: "host-context",
|
|
1098
|
+
key
|
|
1099
|
+
});
|
|
1100
|
+
};
|
|
1101
|
+
}, `typert.contexts.configureHost(${JSON.stringify(key)})`);
|
|
1102
|
+
}
|
|
1103
|
+
registerHost(ctx, key, provider) {
|
|
1104
|
+
validateSegment("Context key", key);
|
|
1105
|
+
validateWireName("Context wire field", provider.wire);
|
|
1106
|
+
validateNonempty("Context wire type symbol", provider.wireTypeSymbol);
|
|
1107
|
+
return this.registerProvider(ctx, this.hosts, "host-context", key, provider);
|
|
1108
|
+
}
|
|
1109
|
+
registerClient(ctx, key, binder) {
|
|
1110
|
+
validateSegment("Context key", key);
|
|
1111
|
+
return this.registerProvider(ctx, this.clients, "client-context", key, binder);
|
|
1112
|
+
}
|
|
1113
|
+
registerProvider(ctx, table, kind, key, provider) {
|
|
1114
|
+
if (table.has(key)) throw new Error(`typert: ${kind} provider "${key}" is already registered`);
|
|
1115
|
+
const entry = {
|
|
1116
|
+
provider,
|
|
1117
|
+
owner: {}
|
|
1118
|
+
};
|
|
1119
|
+
const { changes } = this;
|
|
1120
|
+
return ctx.effect(function* () {
|
|
1121
|
+
table.set(key, entry);
|
|
1122
|
+
changes.emit({
|
|
1123
|
+
kind,
|
|
1124
|
+
key
|
|
1125
|
+
});
|
|
1126
|
+
yield () => {
|
|
1127
|
+
/* v8 ignore next -- duplicate registration is rejected, so this effect remains the key's unique owner. */
|
|
1128
|
+
if (table.get(key) !== entry) return;
|
|
1129
|
+
table.delete(key);
|
|
1130
|
+
changes.emit({
|
|
1131
|
+
kind,
|
|
1132
|
+
key
|
|
1133
|
+
});
|
|
1134
|
+
};
|
|
1135
|
+
}, `typert.contexts.register(${JSON.stringify(key)})`);
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
/**
|
|
1139
|
+
* Registry of generated schemas, package reflection, invocations, and Remote
|
|
1140
|
+
* dependency providers.
|
|
1141
|
+
* @typert service typert
|
|
1142
|
+
*/
|
|
1143
|
+
var TypertRegistry = class extends _deepseek_ai_cordis.Service {
|
|
1144
|
+
schemas = /* @__PURE__ */ new Map();
|
|
1145
|
+
packages = /* @__PURE__ */ new Map();
|
|
1146
|
+
localStore;
|
|
1147
|
+
remoteStore;
|
|
1148
|
+
lookupStore;
|
|
1149
|
+
contextStore;
|
|
1150
|
+
constructor(ctx) {
|
|
1151
|
+
super(ctx, "typert");
|
|
1152
|
+
const report = (change, error) => {
|
|
1153
|
+
ctx.logger.warn(`typert: ${change.kind} observer for "${change.key}" failed`);
|
|
1154
|
+
ctx.logger.warn(error);
|
|
1155
|
+
};
|
|
1156
|
+
this.localStore = new DescriptorStore("local", report);
|
|
1157
|
+
this.remoteStore = new RemoteStore(new DescriptorStore("remote", report));
|
|
1158
|
+
this.lookupStore = new LookupStore(report);
|
|
1159
|
+
this.contextStore = new ContextStore(report);
|
|
1160
|
+
}
|
|
1161
|
+
/** Current-environment invocation definitions. */
|
|
1162
|
+
get local() {
|
|
1163
|
+
const ctx = this.ctx;
|
|
1164
|
+
return {
|
|
1165
|
+
get: (endpoint) => this.localStore.get(endpoint),
|
|
1166
|
+
hasSeen: (endpoint) => this.localStore.hasSeen(endpoint),
|
|
1167
|
+
list: () => this.localStore.list(),
|
|
1168
|
+
subscribe: (listener) => this.localStore.subscribe(ctx, listener)
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
/** Consumer-selected Remote definitions. */
|
|
1172
|
+
get remotes() {
|
|
1173
|
+
return this.remoteStore.view(this.ctx);
|
|
1174
|
+
}
|
|
1175
|
+
/** Host object lookup providers. */
|
|
1176
|
+
get lookups() {
|
|
1177
|
+
return this.lookupStore.view(this.ctx);
|
|
1178
|
+
}
|
|
1179
|
+
/** Host Context providers and Client Context binders. */
|
|
1180
|
+
get contexts() {
|
|
1181
|
+
return this.contextStore.view(this.ctx);
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Register one generated contribution atomically for the calling fiber.
|
|
1185
|
+
* Duplicate package-face identities, schemas, invocation ids, or endpoints
|
|
1186
|
+
* reject the whole batch.
|
|
1187
|
+
* @param contribution - generated schemas, reflection, and Host invocations.
|
|
1188
|
+
* @returns the exact effect disposer that removes this contribution.
|
|
1189
|
+
*/
|
|
1190
|
+
register(contribution) {
|
|
1191
|
+
const packageRecord = this.validatePackage(contribution);
|
|
1192
|
+
const schemaRecords = this.validateSchemas(contribution);
|
|
1193
|
+
const invocations = contribution.invocations;
|
|
1194
|
+
this.localStore.validate(invocations);
|
|
1195
|
+
const owner = {};
|
|
1196
|
+
const { schemas, packages, localStore } = this;
|
|
1197
|
+
return this.ctx.effect(function* () {
|
|
1198
|
+
packages.set(packageRecord.key, packageRecord);
|
|
1199
|
+
for (const record of schemaRecords) schemas.set(record.key, record);
|
|
1200
|
+
localStore.commit(owner, invocations);
|
|
1201
|
+
yield () => {
|
|
1202
|
+
/* v8 ignore else -- duplicate package-face registration is rejected, so this effect remains its unique owner. */
|
|
1203
|
+
if (packages.get(packageRecord.key) === packageRecord) packages.delete(packageRecord.key);
|
|
1204
|
+
for (const record of schemaRecords)
|
|
1205
|
+
/* v8 ignore else -- duplicate schema registration is rejected, so this contribution remains each record's unique owner. */
|
|
1206
|
+
if (schemas.get(record.key) === record) schemas.delete(record.key);
|
|
1207
|
+
localStore.withdraw(owner, invocations);
|
|
1208
|
+
};
|
|
1209
|
+
}, "typert.register()");
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Look up one schema by `<package>#<name>`.
|
|
1213
|
+
* @param key - global schema key.
|
|
1214
|
+
* @returns the live schema record, or `undefined` when absent.
|
|
1215
|
+
*/
|
|
1216
|
+
get(key) {
|
|
1217
|
+
return this.schemas.get(key);
|
|
1218
|
+
}
|
|
1219
|
+
/**
|
|
1220
|
+
* Resolve one required schema.
|
|
1221
|
+
* @param key - global schema key.
|
|
1222
|
+
* @returns the live schema record.
|
|
1223
|
+
* @throws when the key is malformed, the package face is absent, or the schema is not contributed.
|
|
1224
|
+
*/
|
|
1225
|
+
resolve(key) {
|
|
1226
|
+
const record = this.schemas.get(key);
|
|
1227
|
+
if (record !== void 0) return record;
|
|
1228
|
+
const hash = key.indexOf("#");
|
|
1229
|
+
if (hash <= 0 || hash === key.length - 1) throw new Error(`typert: invalid schema key "${key}" — expected "<package>#<name>"`);
|
|
1230
|
+
const packageName = key.slice(0, hash);
|
|
1231
|
+
if ([...this.packages.values()].some((candidate) => candidate.package === packageName)) throw new Error(`typert: cannot resolve "${key}" — package "${packageName}" is registered but contributes no schema named "${key.slice(hash + 1)}"`);
|
|
1232
|
+
throw new Error(`typert: cannot resolve "${key}" — package "${packageName}" has no registered contribution`);
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Enumerate live schemas in registration order.
|
|
1236
|
+
* @param filter - optional package and face restriction.
|
|
1237
|
+
* @returns matching schema records.
|
|
1238
|
+
*/
|
|
1239
|
+
list(filter = {}) {
|
|
1240
|
+
return [...this.schemas.values()].filter((record) => matches(record, filter));
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Look up generated reflection for one package face.
|
|
1244
|
+
* @param packageName - exact npm package name.
|
|
1245
|
+
* @param face - face to query; defaults to the host runtime.
|
|
1246
|
+
* @returns the live package record, or `undefined` when absent.
|
|
1247
|
+
*/
|
|
1248
|
+
getPackage(packageName, face = "host") {
|
|
1249
|
+
return this.packages.get(typertPackageKey(packageName, face));
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Enumerate generated package reflection in registration order.
|
|
1253
|
+
* @param filter - optional package and face restriction.
|
|
1254
|
+
* @returns matching package records.
|
|
1255
|
+
*/
|
|
1256
|
+
listPackages(filter = {}) {
|
|
1257
|
+
return [...this.packages.values()].filter((record) => matches(record, filter));
|
|
1258
|
+
}
|
|
1259
|
+
/**
|
|
1260
|
+
* Project a live Zod schema to JSON Schema without caching the result.
|
|
1261
|
+
* @param key - global schema key.
|
|
1262
|
+
* @param params - Zod projection parameters.
|
|
1263
|
+
* @returns a fresh JSON Schema document.
|
|
1264
|
+
*/
|
|
1265
|
+
toJSONSchema(key, params) {
|
|
1266
|
+
return toJSONSchema(this.resolve(key).schema, params);
|
|
1267
|
+
}
|
|
1268
|
+
validatePackage(contribution) {
|
|
1269
|
+
validateSegment("package name", contribution.package);
|
|
1270
|
+
const face = contribution.face;
|
|
1271
|
+
if (face !== "host" && face !== "client") throw new Error(`typert: invalid face ${JSON.stringify(face)} — expected "host" or "client"`);
|
|
1272
|
+
const key = typertPackageKey(contribution.package, contribution.face);
|
|
1273
|
+
if (this.packages.has(key)) throw new Error(`typert: package face "${key}" is already registered`);
|
|
1274
|
+
return {
|
|
1275
|
+
package: contribution.package,
|
|
1276
|
+
face,
|
|
1277
|
+
key,
|
|
1278
|
+
model: contribution.model
|
|
1279
|
+
};
|
|
1280
|
+
}
|
|
1281
|
+
validateSchemas(contribution) {
|
|
1282
|
+
const records = [];
|
|
1283
|
+
const batch = /* @__PURE__ */ new Set();
|
|
1284
|
+
for (const schema of contribution.schemas) {
|
|
1285
|
+
validateSegment("schema name", schema.name);
|
|
1286
|
+
const key = typertKey(contribution.package, schema.name);
|
|
1287
|
+
if (batch.has(key) || this.schemas.has(key)) throw new Error(`typert: schema "${key}" is already registered`);
|
|
1288
|
+
batch.add(key);
|
|
1289
|
+
records.push({
|
|
1290
|
+
...schema,
|
|
1291
|
+
package: contribution.package,
|
|
1292
|
+
face: contribution.face,
|
|
1293
|
+
key
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
return records;
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
function matches(record, filter) {
|
|
1300
|
+
return (filter.package === void 0 || record.package === filter.package) && (filter.face === void 0 || record.face === filter.face);
|
|
1301
|
+
}
|
|
1302
|
+
function validateInvocation(descriptor) {
|
|
1303
|
+
validateNonempty("invocation id", descriptor.id);
|
|
1304
|
+
validateSegment("invocation service key", descriptor.service);
|
|
1305
|
+
validateWireName("invocation namespace", descriptor.namespace);
|
|
1306
|
+
validateWireName("invocation method", descriptor.method);
|
|
1307
|
+
if (descriptor.implementation !== void 0) validateWireName("invocation implementation method", descriptor.implementation);
|
|
1308
|
+
validateCodec(descriptor.result, `${descriptor.id} result`);
|
|
1309
|
+
const wires = /* @__PURE__ */ new Set();
|
|
1310
|
+
for (const parameter of descriptor.parameters) {
|
|
1311
|
+
validateWireName("parameter name", parameter.name);
|
|
1312
|
+
validateWireName("parameter wire field", parameter.wire);
|
|
1313
|
+
if (wires.has(parameter.wire)) throw new Error(`typert: invocation "${descriptor.id}" repeats wire field "${parameter.wire}"`);
|
|
1314
|
+
wires.add(parameter.wire);
|
|
1315
|
+
if (parameter.source === "lookup") {
|
|
1316
|
+
if (parameter.acceptsUndefined !== void 0) throw new Error(`typert: invocation "${descriptor.id}" lookup parameter "${parameter.name}" cannot accept undefined`);
|
|
1317
|
+
if (parameter.lookup === void 0) throw new Error(`typert: invocation "${descriptor.id}" lookup parameter "${parameter.name}" has no lookup key`);
|
|
1318
|
+
validateSegment("lookup key", parameter.lookup);
|
|
1319
|
+
} else if (parameter.lookup !== void 0) throw new Error(`typert: invocation "${descriptor.id}" JSON parameter "${parameter.name}" declares a lookup key`);
|
|
1320
|
+
validateCodec(parameter.codec, `${descriptor.id} parameter ${parameter.name}`);
|
|
1321
|
+
}
|
|
1322
|
+
const cancellation = descriptor.cancellation;
|
|
1323
|
+
if (cancellation !== void 0 && cancellation.parameter !== "signal") throw new Error(`typert: invocation "${descriptor.id}" cancellation parameter must be "signal"`);
|
|
1324
|
+
if (descriptor.scope !== void 0) {
|
|
1325
|
+
if (descriptor.invocation.kind !== "direct") throw new Error(`typert: invocation "${descriptor.id}" Context receiver cannot declare a direct scope projection`);
|
|
1326
|
+
validateSegment("scope Context key", descriptor.scope.context);
|
|
1327
|
+
validateWireName("scope wire field", descriptor.scope.wire);
|
|
1328
|
+
const lookups = descriptor.parameters.filter((candidate) => candidate.source === "lookup");
|
|
1329
|
+
const parameter = lookups.length === 1 ? lookups[0] : void 0;
|
|
1330
|
+
if (parameter === void 0 || parameter.wire !== descriptor.scope.wire || parameter.lookup !== descriptor.scope.context) throw new Error(`typert: invocation "${descriptor.id}" scope wire "${descriptor.scope.wire}" must select its only lookup parameter`);
|
|
1331
|
+
}
|
|
1332
|
+
if (descriptor.invocation.kind === "context") {
|
|
1333
|
+
validateSegment("Context key", descriptor.invocation.context);
|
|
1334
|
+
validateWireName("Context wire field", descriptor.invocation.wire);
|
|
1335
|
+
if (wires.has(descriptor.invocation.wire)) throw new Error(`typert: invocation "${descriptor.id}" repeats wire field "${descriptor.invocation.wire}"`);
|
|
1336
|
+
validateCodec(descriptor.invocation.codec, `${descriptor.id} Context`);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
function validateCodec(codec, subject) {
|
|
1340
|
+
if (codec.mode === "src-json") return;
|
|
1341
|
+
validateNonempty(`${subject} type symbol`, codec.typeSymbol);
|
|
1342
|
+
if (typeof codec.schema.parse !== "function") throw new Error(`typert: ${subject} strict codec has no parse() method`);
|
|
1343
|
+
}
|
|
1344
|
+
function validateWireName(subject, value) {
|
|
1345
|
+
if (value === "." || value === ".." || !/^[A-Za-z0-9_$.-]+$/.test(value)) throw new Error(`typert: invalid ${subject} "${value}" — must contain only RPC endpoint segment characters`);
|
|
1346
|
+
}
|
|
1347
|
+
function validateSegment(subject, value) {
|
|
1348
|
+
if (value.length === 0 || value.includes("#")) throw new Error(`typert: invalid ${subject} "${value}" — must be nonempty and must not contain "#"`);
|
|
1349
|
+
}
|
|
1350
|
+
function validateNonempty(subject, value) {
|
|
1351
|
+
if (value.length === 0) throw new Error(`typert: invalid ${subject} — must be nonempty`);
|
|
1352
|
+
}
|
|
1353
|
+
//#endregion
|
|
1354
|
+
//#region lib/types/client/index.js
|
|
1355
|
+
/** Browser face of the shared Typert runtime registry. */
|
|
1356
|
+
/** Required services: none; this is the Client reflection root. */
|
|
1357
|
+
const inject = [];
|
|
1358
|
+
/**
|
|
1359
|
+
* Install the same registry implementation used by the Host face.
|
|
1360
|
+
* @param ctx - Client Cordis root.
|
|
1361
|
+
*/
|
|
1362
|
+
function apply(ctx) {
|
|
1363
|
+
new TypertRegistry(ctx);
|
|
1364
|
+
}
|
|
1365
|
+
//#endregion
|
|
1366
|
+
exports.apply = apply;
|
|
1367
|
+
exports.inject = inject;
|
|
1368
|
+
return module.exports;
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1372
|
+
//# sourceMappingURL=client.js.map
|