@nudojs/service 1.0.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -7
- package/dist/analysis-_DlXLC-L.d.ts +281 -0
- package/dist/analysis.d.ts +8 -0
- package/dist/analysis.js +61 -0
- package/dist/analyzer-types-CfBrPK9L.d.ts +158 -0
- package/dist/call-record-CkyCFkT9.d.ts +33 -0
- package/dist/chunk-EG6FYQLI.js +89 -0
- package/dist/chunk-J2PUE4NV.js +235 -0
- package/dist/chunk-NQXAF4LJ.js +3739 -0
- package/dist/{chunk-2VHITMTM.js → chunk-ZXVAX7DE.js} +343 -16
- package/dist/config-DDB588oA.d.ts +114 -0
- package/dist/emit/index.d.ts +619 -0
- package/dist/emit/index.js +3775 -0
- package/dist/env-loader-fj0TSCcA.d.ts +20 -0
- package/dist/evaluator/evaluator-api.d.ts +5 -12
- package/dist/evaluator/evaluator-api.js +9 -1
- package/dist/index.d.ts +355 -843
- package/dist/index.js +270 -5781
- package/dist/what-if-mIo7I5Ii.d.ts +21 -0
- package/package.json +20 -9
- package/dist/config-NqDRWWpn.d.ts +0 -68
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
import { C as CallRecord } from '../call-record-CkyCFkT9.js';
|
|
2
|
+
import { L as LoadModule } from '../what-if-mIo7I5Ii.js';
|
|
3
|
+
export { T as TypeBinding, i as injectBindings, t as typeExprToDirective } from '../what-if-mIo7I5Ii.js';
|
|
4
|
+
import { NudoConstraint, Abs } from '@nudojs/core';
|
|
5
|
+
import { A as AnalysisResult, F as FunctionAnalysis, S as SourceLocation } from '../analyzer-types-CfBrPK9L.js';
|
|
6
|
+
import '@babel/types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `nudo contract` 的打印数据源(design-refine-derivation §11 第 0 步):
|
|
10
|
+
* 逐顶层函数展示有效契约分层——effectiveInterface 命中(手写契约 / 侧车
|
|
11
|
+
* 生成段)时 params/returns 用 formatConstraint 组合式显示;未命中走
|
|
12
|
+
* implicit:优先 CaseResult.argAbs / FunctionAnalysis.combinedAbs(无损
|
|
13
|
+
* Abs 源),展示用 formatShape(外延口径,不强求约束式、不带 conf)。
|
|
14
|
+
*
|
|
15
|
+
* autoBind 沿 package.json#nudo.contract(findProjectConfig → interfaceConfig)
|
|
16
|
+
* 下传,可用 opts 覆盖(测试 / CLI 显式开关);读盘用 defaultLoadModule
|
|
17
|
+
* (与 check 的 refine 解析同一扩展名表)。
|
|
18
|
+
*
|
|
19
|
+
* B3 Phase B:`nudo.cache` / NUDO_CACHE_DIR 打开时,整文件 effectiveInterface
|
|
20
|
+
* 表(含 implicit 负缓存 null)落盘;二次冷启动跳过侧车 exec / 契约合并。
|
|
21
|
+
* 缓存只服务打印/表面,不加速 B-path 分析(design-persistent-cache §0)。
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
type InterfaceSurfaceEntry = {
|
|
25
|
+
fn: string;
|
|
26
|
+
/** 本文件 named export(自动绑定边界口径:localNamedExports) */
|
|
27
|
+
kind: "export" | "local";
|
|
28
|
+
source: "handwritten" | "generated" | "implicit";
|
|
29
|
+
params: Array<{
|
|
30
|
+
name: string;
|
|
31
|
+
display: string;
|
|
32
|
+
}>;
|
|
33
|
+
returns?: string;
|
|
34
|
+
};
|
|
35
|
+
type InterfaceSurfaceOpts = {
|
|
36
|
+
/** 覆盖项目配置的 autoBind(默认 findProjectConfig → interfaceConfig) */
|
|
37
|
+
autoBind?: boolean;
|
|
38
|
+
/** 模块源码装载器(测试注入);默认 defaultLoadModule 真实读盘 */
|
|
39
|
+
loadModule?: LoadModule;
|
|
40
|
+
/** 跨文件调用记录(--from 采集):implicit 展示的实参域原料 */
|
|
41
|
+
records?: CallRecord[];
|
|
42
|
+
/** 打开 buffer 覆盖磁盘源码(E5:agent/LSP 与 hover 同口径) */
|
|
43
|
+
source?: string;
|
|
44
|
+
};
|
|
45
|
+
/** 单条 interface 打印行(CLI runInterface 与 LSP agent 面共用) */
|
|
46
|
+
declare function formatInterfaceSurfaceLine(e: InterfaceSurfaceEntry): string;
|
|
47
|
+
/**
|
|
48
|
+
* 单文件 interface 表面:analyzer 推断结果给出函数清单与 implicit 展示,
|
|
49
|
+
* effectiveInterface 给出契约命中(手写 > 生成段)。诊断 side-channel
|
|
50
|
+
* 在收尾时取走丢弃——打印命令不执法,interface-load 等错误留给 check 路径。
|
|
51
|
+
*/
|
|
52
|
+
declare function interfaceSurface(filePath: string, opts?: InterfaceSurfaceOpts): Promise<InterfaceSurfaceEntry[]>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* `nudo contract --emit` 的写盘器(design-refine-derivation §5.4 / §7.3 / §11):
|
|
56
|
+
* 把分析产出的调用点域投影(joinThenProject,先 Abs join 再投影)固化为侧车
|
|
57
|
+
* `*.nudo.js` / `*.nudo.ts` 的 `@generated` 段——`export const <fn> = fn({…}, …)`。
|
|
58
|
+
*
|
|
59
|
+
* - 生成段 = 三行:`@generated` 头注释 + `// source: <相对file>:<fn>` + export 行。
|
|
60
|
+
* DSL 由 formatConstraint 产出,**写入前 round-trip 自检**(生成文本经
|
|
61
|
+
* execNudoModule 求值、导出须 isNudoConstraint 且 fn 槽存在):展示兜底形态
|
|
62
|
+
* (`x?:` 可选字段、`.eq()` 伪链、`{谓词原文}`)不是合法 DSL,自检拦下 →
|
|
63
|
+
* not-projectable 跳过,不写垃圾。
|
|
64
|
+
* - 手写导出永不覆盖:目标名已是侧车手写绑定 → 跳过写入并报
|
|
65
|
+
* `nudo:interface-name-clash`(error,手写优先)。
|
|
66
|
+
* - mode=update:剥离全部生成段再重排(幂等;非目标的既有生成段原样保留,
|
|
67
|
+
* 不随 --fn 丢失);mode=add:仅追加缺失段。
|
|
68
|
+
* - 目标过滤(§7.3):--fn 白名单 > --all 全量 > 默认只刷新已有生成段
|
|
69
|
+
* (「无根只处理已存在生成段」;Phase 1 无 root 闭包下行推导)。
|
|
70
|
+
* - autoBind=false 不影响 emit(显式动作,非 ambient 加载)。
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
type EmitInterfaceSkipReason = "name-clash" | "not-projectable" | "not-an-export" | "no-change"
|
|
74
|
+
/** package.json#nudo.contract.emit 白名单拒绝 */
|
|
75
|
+
| "emit-denied"
|
|
76
|
+
/** 手工合并的多声明符 @generated 段:按段原子保留,不拆不重写 */
|
|
77
|
+
| "multi-declarator";
|
|
78
|
+
type EmitInterfaceOpts = {
|
|
79
|
+
/** 目标导出名白名单(Phase 1:只过滤目标文件自身的导出;跨文件 root 闭包 emit 是 Phase 2 下行推导能力) */
|
|
80
|
+
fnNames?: string[];
|
|
81
|
+
/** update=剥离全部生成段再重排(幂等);add=仅追加缺失段 */
|
|
82
|
+
mode: "add" | "update";
|
|
83
|
+
/** 全部顶层导出(显式 opt-in,CLI 侧文档警告勿默认) */
|
|
84
|
+
all?: boolean;
|
|
85
|
+
/** 不写盘,返回 unifiedDiff */
|
|
86
|
+
dryRun?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* 跨文件调用记录(--from 采集):域根导出(本文件无调用点、仅有
|
|
89
|
+
* 外部使用现场记录)的投影原料;缺省时仅用本文件调用点证据。
|
|
90
|
+
*/
|
|
91
|
+
records?: CallRecord[];
|
|
92
|
+
/** 缓冲源(E5:agent/LSP 与 validate 同源);缺省读盘 */
|
|
93
|
+
source?: string;
|
|
94
|
+
/** 模块装载器(buffer-aware 侧车可见);缺省 defaultLoadModule */
|
|
95
|
+
loadModule?: (spec: string, fromFile: string) => string | undefined;
|
|
96
|
+
};
|
|
97
|
+
type EmitInterfaceResult = {
|
|
98
|
+
written: string[];
|
|
99
|
+
skipped: Array<{
|
|
100
|
+
fn: string;
|
|
101
|
+
reason: EmitInterfaceSkipReason;
|
|
102
|
+
}>;
|
|
103
|
+
changed: boolean;
|
|
104
|
+
diff?: string;
|
|
105
|
+
issues: Array<{
|
|
106
|
+
code: string;
|
|
107
|
+
severity: "error" | "warning";
|
|
108
|
+
message: string;
|
|
109
|
+
}>;
|
|
110
|
+
/** 侧车绝对路径(新建或已有) */
|
|
111
|
+
sidecarPath: string;
|
|
112
|
+
/**
|
|
113
|
+
* 默认过滤(无 --fn/--all)且侧车无既有 @generated 段可刷 —— 调用方
|
|
114
|
+
* 用它把「no interface changes」解释成首次 emit 的用法提示,而非漂移。
|
|
115
|
+
*/
|
|
116
|
+
emptyDefaultTargets?: boolean;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* 单文件 emit:分析 → 逐目标投影/自检 → 组装侧车内容 →(非 dryRun)写盘。
|
|
120
|
+
* 诊断 side-channel(round-trip 自检触发的 refine/interface diags)收尾取走丢弃。
|
|
121
|
+
*/
|
|
122
|
+
declare function emitInterface(filePath: string, opts: EmitInterfaceOpts): Promise<EmitInterfaceResult>;
|
|
123
|
+
/**
|
|
124
|
+
* emit 摘要行(CLI runInterfaceEmit 与 LSP agent 面共用;路径由调用方按
|
|
125
|
+
* 展示口径传入——CLI 传 cwd 相对、agent 传绝对路径)。
|
|
126
|
+
*/
|
|
127
|
+
declare function formatEmitSummary(sourcePath: string, sidecarRel: string, result: EmitInterfaceResult): string[];
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* `nudo contract --draft`:从已有 JS **逻辑** 生成 contract 草稿。
|
|
131
|
+
*
|
|
132
|
+
* 产品位(代码优先 / 迁移):先写实现,再反推可审阅的 `fn({…}, …)` 草稿;
|
|
133
|
+
* 人审后迁入 `*.nudo.js` 才成为契约。
|
|
134
|
+
*
|
|
135
|
+
* 证据分层(与 C0 一致:草稿 ≠ ambient 义务):
|
|
136
|
+
* - callsite / directive case → joinThenProject 值域(迁移最可信)
|
|
137
|
+
* - body 触达(**仅草稿展示**)→ 参数上被读到的字段名建议;不进 check
|
|
138
|
+
* - generalize symbolic → 返回位兜底
|
|
139
|
+
* - 无证据 → 参数槽省略 + 注释 TODO(不发明义务)
|
|
140
|
+
* - 已有 handwritten 契约 → **跳过**(手写优先,不覆盖)
|
|
141
|
+
*
|
|
142
|
+
* 写盘:默认只打印;`--write` 写入 `<file>.nudo.draft.js`——**不会**被
|
|
143
|
+
* sidecar 自动绑定(loadModule 只认 `*.nudo.js`)。审阅后复制进正式侧车。
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* DraftEvidence `body` = 仅来自函数体对形参的成员读取(草稿建议,非义务)。
|
|
148
|
+
* check / effectiveInterface **永不**消费该档。
|
|
149
|
+
*/
|
|
150
|
+
type DraftEvidence = "callsite" | "directive" | "symbolic" | "body" | "none";
|
|
151
|
+
type InterfaceDraftEntry = {
|
|
152
|
+
fn: string;
|
|
153
|
+
/** 全部形参(含无证据槽,便于人读) */
|
|
154
|
+
params: Array<{
|
|
155
|
+
name: string;
|
|
156
|
+
constraint?: NudoConstraint;
|
|
157
|
+
display: string;
|
|
158
|
+
/** false = 无证据,DSL 对象里省略该槽 */
|
|
159
|
+
projected: boolean;
|
|
160
|
+
/** 函数体读到的字段名(草稿建议;与 projected 无关) */
|
|
161
|
+
bodyAccesses?: string[];
|
|
162
|
+
}>;
|
|
163
|
+
returns?: {
|
|
164
|
+
constraint?: NudoConstraint;
|
|
165
|
+
display: string;
|
|
166
|
+
projected: boolean;
|
|
167
|
+
};
|
|
168
|
+
paramEvidence: DraftEvidence;
|
|
169
|
+
returnEvidence: DraftEvidence;
|
|
170
|
+
skipped?: "handwritten" | "not-an-export";
|
|
171
|
+
/** 草稿 DSL:`fn({ … }, …)`;handwritten / 非导出时 undefined */
|
|
172
|
+
dsl?: string;
|
|
173
|
+
};
|
|
174
|
+
type InterfaceDraftOpts = {
|
|
175
|
+
fnNames?: string[];
|
|
176
|
+
records?: CallRecord[];
|
|
177
|
+
loadModule?: LoadModule;
|
|
178
|
+
/**
|
|
179
|
+
* Accepted for API compatibility; **ignored**. The handwritten-contract probe
|
|
180
|
+
* always uses `effectiveInterface(..., { autoBind: true })` so draft skips
|
|
181
|
+
* disk sidecars even when ambient autoBind is off (product: draft asks
|
|
182
|
+
* "does a contract already exist?", not "is ambient binding on?").
|
|
183
|
+
*/
|
|
184
|
+
autoBind?: boolean;
|
|
185
|
+
/** 默认 true:收集 body 成员读取作草稿建议(永不进 check) */
|
|
186
|
+
bodyAccesses?: boolean;
|
|
187
|
+
/** 打开 buffer 源(E5:与 hover/interface 同口径) */
|
|
188
|
+
source?: string;
|
|
189
|
+
};
|
|
190
|
+
type InterfaceDraftResult = {
|
|
191
|
+
file: string;
|
|
192
|
+
entries: InterfaceDraftEntry[];
|
|
193
|
+
draftSource: string;
|
|
194
|
+
sidecarPath: string;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Draft-only:收集每个顶层函数形参上的成员读取键(`user.name` → name)。
|
|
198
|
+
* **不是** C0 禁止的 body→义务通道——只进草稿注释/建议,check 不读此表。
|
|
199
|
+
*/
|
|
200
|
+
declare function collectParamBodyAccesses(source: string): Map<string, Map<string, Set<string>>>;
|
|
201
|
+
/**
|
|
202
|
+
* 为单文件顶层导出生成 interface 草稿(不写盘)。
|
|
203
|
+
* handwritten 跳过;已有 @generated 仍出草稿(便于对照)。
|
|
204
|
+
*/
|
|
205
|
+
declare function draftInterface(filePath: string, opts?: InterfaceDraftOpts): Promise<InterfaceDraftResult>;
|
|
206
|
+
/** 草稿模块文本(人读 + 可复制到 *.nudo.js / *.nudo.ts) */
|
|
207
|
+
declare function formatDraftModule(filePath: string, entries: InterfaceDraftEntry[], sidecarPath?: string): string;
|
|
208
|
+
/** `lib.js|ts` → `lib.nudo.draft.js|ts`(不进 ambient sidecar 表) */
|
|
209
|
+
declare function sidecarDraftPath(filePath: string): string;
|
|
210
|
+
type WriteDraftResult = {
|
|
211
|
+
draftPath: string;
|
|
212
|
+
written: boolean;
|
|
213
|
+
changed: boolean;
|
|
214
|
+
draftable: boolean;
|
|
215
|
+
draftSource: string;
|
|
216
|
+
};
|
|
217
|
+
/** Parse-layer draftable: at least one entry has generated DSL and was not skipped */
|
|
218
|
+
declare function isDraftableEntry(entries: ReadonlyArray<Pick<InterfaceDraftEntry, "dsl" | "skipped">>): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* 写入 `*.nudo.draft.js`(覆盖草稿文件本身;不碰正式 `*.nudo.js`)。
|
|
221
|
+
* 基础路径防护:拒绝 node_modules;拒绝 draft 路径与正式侧车重合;
|
|
222
|
+
* 拒绝 draft 路径落在源文件目录之外的穿越。
|
|
223
|
+
*
|
|
224
|
+
* `opts.entries` / `opts.draftable`:解析层判定(优先)。缺省时用 Unicode
|
|
225
|
+
* 感知 export 正则兜底——`\w` 会静默丢掉 `计算` 这类标识符。
|
|
226
|
+
*/
|
|
227
|
+
declare function writeInterfaceDraft(filePath: string, draftSource: string, opts?: {
|
|
228
|
+
dryRun?: boolean;
|
|
229
|
+
projectDir?: string;
|
|
230
|
+
entries?: ReadonlyArray<Pick<InterfaceDraftEntry, "dsl" | "skipped">>;
|
|
231
|
+
draftable?: boolean;
|
|
232
|
+
}): WriteDraftResult;
|
|
233
|
+
declare function formatDraftSummary(sourceRel: string, draftRel: string, result: InterfaceDraftResult, write?: WriteDraftResult): string[];
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Derivation slot projection(Abs → 组合式 DSL 投影缝)。
|
|
237
|
+
* 自 interface-derivation.ts 机械拆出;语义未改。
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
type ConstraintSourceExpr = {
|
|
241
|
+
expr: string;
|
|
242
|
+
importFrom?: string;
|
|
243
|
+
importName?: string;
|
|
244
|
+
};
|
|
245
|
+
type DerivedParam = {
|
|
246
|
+
name: string;
|
|
247
|
+
constraint: NudoConstraint;
|
|
248
|
+
dsl: string;
|
|
249
|
+
prelude: string[];
|
|
250
|
+
imports: Array<{
|
|
251
|
+
name: string;
|
|
252
|
+
from: string;
|
|
253
|
+
}>;
|
|
254
|
+
/** 单链组合式投影时的推导图 root 节点 id(返回位相对锚定用) */
|
|
255
|
+
rootNodeId?: number;
|
|
256
|
+
/** 该参数位自 root 起消耗的 shift 步数(与 prelude 行数无关,读图) */
|
|
257
|
+
shiftCount?: number;
|
|
258
|
+
};
|
|
259
|
+
type DerivedExport = {
|
|
260
|
+
file: string;
|
|
261
|
+
fn: string;
|
|
262
|
+
paramNames: string[];
|
|
263
|
+
params: DerivedParam[];
|
|
264
|
+
returns?: {
|
|
265
|
+
constraint: NudoConstraint;
|
|
266
|
+
dsl: string;
|
|
267
|
+
prelude: string[];
|
|
268
|
+
imports: Array<{
|
|
269
|
+
name: string;
|
|
270
|
+
from: string;
|
|
271
|
+
}>;
|
|
272
|
+
};
|
|
273
|
+
/** `lib.js:add4` */
|
|
274
|
+
derivedFrom: string;
|
|
275
|
+
compositional: boolean;
|
|
276
|
+
underivable?: boolean;
|
|
277
|
+
};
|
|
278
|
+
type RootDeriveOpts = {
|
|
279
|
+
loadModule?: LoadModule;
|
|
280
|
+
autoBind?: boolean;
|
|
281
|
+
fnNames?: string[];
|
|
282
|
+
/**
|
|
283
|
+
* true:只刷新目标侧车里**已存在**的 @generated 段(CLI 无 --fn/--all 时
|
|
284
|
+
* 的默认行为——不发明新下游契约)。false/省略:闭包内全部可推导导出。
|
|
285
|
+
*/
|
|
286
|
+
refreshExistingOnly?: boolean;
|
|
287
|
+
};
|
|
288
|
+
type RootDeriveResult = {
|
|
289
|
+
roots: string[];
|
|
290
|
+
derived: DerivedExport[];
|
|
291
|
+
hasRoot: boolean;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
declare function extractFnConstraintSources(sidecarSrc: string, fnName: string): {
|
|
295
|
+
params: Record<string, ConstraintSourceExpr>;
|
|
296
|
+
returns?: ConstraintSourceExpr;
|
|
297
|
+
};
|
|
298
|
+
/**
|
|
299
|
+
* 入口:对 filePath 做 root 驱动下行推导。
|
|
300
|
+
*/
|
|
301
|
+
declare function deriveFromRoot(filePath: string, opts?: RootDeriveOpts): RootDeriveResult;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* 组装生成段(组合式 + import + prelude)。
|
|
305
|
+
* importFrom 相对 root 侧车解析,再相对 target 侧车写出。
|
|
306
|
+
*
|
|
307
|
+
* `takenNames`:侧车顶层已占用标识符(手写 / 既有生成段 / 本批先前段)。
|
|
308
|
+
* 同文件多导出时对 import local 与 prelude local 做避让改写,
|
|
309
|
+
* 保证拼出的侧车在模块作用域内无重复声明。
|
|
310
|
+
*/
|
|
311
|
+
declare function formatDerivedSection(row: DerivedExport, opts: {
|
|
312
|
+
rootSidecarDir: string;
|
|
313
|
+
targetSidecarDir: string;
|
|
314
|
+
takenNames?: Iterable<string>;
|
|
315
|
+
}): {
|
|
316
|
+
text: string;
|
|
317
|
+
usedNames: string[];
|
|
318
|
+
} | undefined;
|
|
319
|
+
|
|
320
|
+
type EmitDerivedResult = {
|
|
321
|
+
/** 被写/将写的下游侧车(绝对路径) */
|
|
322
|
+
sidecars: Array<{
|
|
323
|
+
file: string;
|
|
324
|
+
sidecarPath: string;
|
|
325
|
+
fn: string;
|
|
326
|
+
written: boolean;
|
|
327
|
+
changed: boolean;
|
|
328
|
+
skipped?: "name-clash" | "not-projectable" | "underivable" | "no-change";
|
|
329
|
+
diff?: string;
|
|
330
|
+
issues: Array<{
|
|
331
|
+
code: string;
|
|
332
|
+
severity: "error" | "warning" | "info";
|
|
333
|
+
message: string;
|
|
334
|
+
}>;
|
|
335
|
+
}>;
|
|
336
|
+
hasRoot: boolean;
|
|
337
|
+
roots: string[];
|
|
338
|
+
/** 根在别处 / 无契约根且无已存在生成段 → info */
|
|
339
|
+
entryOnly?: boolean;
|
|
340
|
+
};
|
|
341
|
+
declare function emitDerivedFromRoot(rootFile: string, opts: {
|
|
342
|
+
fnNames?: string[];
|
|
343
|
+
mode: "add" | "update";
|
|
344
|
+
dryRun?: boolean;
|
|
345
|
+
loadModule?: LoadModule;
|
|
346
|
+
autoBind?: boolean;
|
|
347
|
+
/** 只刷新目标侧车里已存在的 @generated 段(不发明新下游契约) */
|
|
348
|
+
refreshExistingOnly?: boolean;
|
|
349
|
+
}): EmitDerivedResult;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Abs → TS 类型串。有损:pred / 非 lit term 落到 shape 基类型。
|
|
353
|
+
* `typeVars`:term var id → TS 类型参数名(HOF 泛型投影时传入;
|
|
354
|
+
* `any`+var 在此映射下渲染为该参数名,否则 `unknown`)。
|
|
355
|
+
*/
|
|
356
|
+
declare function absToTSType(a: Abs, typeVars?: Map<string, string>): string;
|
|
357
|
+
/**
|
|
358
|
+
* 为单个函数生成 .d.ts 声明行(JSDoc + 单一 widen 主签名)。
|
|
359
|
+
* 有 hof 关系时优先泛型投影(C3.3);否则 case-widen。
|
|
360
|
+
* service 的 generateDts 与 CLI `--dts`(infer/watch)共用本函数,
|
|
361
|
+
* 两条路径输出保持一致。
|
|
362
|
+
*/
|
|
363
|
+
declare function generateFunctionDtsLines(fn: FunctionAnalysis): string[];
|
|
364
|
+
declare function generateDts(result: AnalysisResult): string;
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Abs → 生态 schema 投影(单向有损)。
|
|
368
|
+
*
|
|
369
|
+
* 优先走 core `absToConstraint`(与 interface/check 同一投影语义),
|
|
370
|
+
* 再转成中间层 SchemaNode;投影失败时退回 shape 尽力提取并记 dropped。
|
|
371
|
+
* Dialect 只负责 Node → 源码字符串;Abs 才是真理源。
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
type SchemaDialect = "zod";
|
|
375
|
+
type SchemaRefinement = {
|
|
376
|
+
kind: "numBound";
|
|
377
|
+
op: "gt" | "ge" | "lt" | "le";
|
|
378
|
+
n: number;
|
|
379
|
+
} | {
|
|
380
|
+
kind: "int";
|
|
381
|
+
} | {
|
|
382
|
+
kind: "strMin";
|
|
383
|
+
n: number;
|
|
384
|
+
} | {
|
|
385
|
+
kind: "strMax";
|
|
386
|
+
n: number;
|
|
387
|
+
};
|
|
388
|
+
type SchemaNode = {
|
|
389
|
+
k: "lit";
|
|
390
|
+
value: string | number | boolean | null | undefined;
|
|
391
|
+
} | {
|
|
392
|
+
k: "prim";
|
|
393
|
+
type: "number" | "string" | "boolean" | "bigint" | "symbol";
|
|
394
|
+
refinements: SchemaRefinement[];
|
|
395
|
+
} | {
|
|
396
|
+
k: "obj";
|
|
397
|
+
slots: Array<{
|
|
398
|
+
key: string;
|
|
399
|
+
node: SchemaNode;
|
|
400
|
+
optional?: boolean;
|
|
401
|
+
}>;
|
|
402
|
+
} | {
|
|
403
|
+
k: "arr";
|
|
404
|
+
element: SchemaNode;
|
|
405
|
+
} | {
|
|
406
|
+
k: "tuple";
|
|
407
|
+
elements: SchemaNode[];
|
|
408
|
+
} | {
|
|
409
|
+
k: "union";
|
|
410
|
+
members: SchemaNode[];
|
|
411
|
+
} | {
|
|
412
|
+
k: "fn";
|
|
413
|
+
} | {
|
|
414
|
+
k: "promise";
|
|
415
|
+
inner: SchemaNode;
|
|
416
|
+
} | {
|
|
417
|
+
k: "brand";
|
|
418
|
+
name: string;
|
|
419
|
+
} | {
|
|
420
|
+
k: "never";
|
|
421
|
+
} | {
|
|
422
|
+
k: "unknown";
|
|
423
|
+
};
|
|
424
|
+
type SchemaProjection = {
|
|
425
|
+
source: string;
|
|
426
|
+
dialect: SchemaDialect;
|
|
427
|
+
dropped: string[];
|
|
428
|
+
};
|
|
429
|
+
/** NudoConstraint → SchemaNode(与 absToConstraint 投影语义对齐) */
|
|
430
|
+
declare function constraintToSchemaNode(c: NudoConstraint): SchemaNode;
|
|
431
|
+
/** Abs → SchemaNode + dropped(优先 core absToConstraint;失败则 shape 尽力) */
|
|
432
|
+
declare function absToSchemaNode(a: Abs): {
|
|
433
|
+
node: SchemaNode;
|
|
434
|
+
dropped: string[];
|
|
435
|
+
};
|
|
436
|
+
declare function schemaNodeToZod(node: SchemaNode): string;
|
|
437
|
+
declare function projectAbsToSchema(a: Abs, opts?: {
|
|
438
|
+
dialect?: SchemaDialect;
|
|
439
|
+
}): SchemaProjection;
|
|
440
|
+
declare function absToSchemaSource(a: Abs, opts?: {
|
|
441
|
+
dialect?: SchemaDialect;
|
|
442
|
+
}): string;
|
|
443
|
+
type ZodModuleProjection = {
|
|
444
|
+
source: string;
|
|
445
|
+
dialect: SchemaDialect;
|
|
446
|
+
dropped: string[];
|
|
447
|
+
};
|
|
448
|
+
/**
|
|
449
|
+
* Abs 导出表 → 可 import 的 zod JS 模块源码。
|
|
450
|
+
* 形如 `import { z } from "zod"; export const name = z...;`
|
|
451
|
+
*/
|
|
452
|
+
declare function absToZodSchemaModule(exports: Record<string, Abs>, opts?: {
|
|
453
|
+
banner?: string;
|
|
454
|
+
}): ZodModuleProjection;
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Abs / SchemaNode → Standard Schema v1 运行时模块(单向有损投影)。
|
|
458
|
+
*
|
|
459
|
+
* 产物是零第三方依赖的 TS/JS 模块:每个导出实现 `~standard` Props
|
|
460
|
+
* (version=1, vendor="nudo", validate)。validate 对 SchemaNode 做
|
|
461
|
+
* 结构 + 可表达 refinement 执法;落不了的 pred 不在此假装精确。
|
|
462
|
+
*
|
|
463
|
+
* 协议:https://standardschema.dev —— 运行时互操作出口,不替代 nudo check。
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
type StandardSchemaIssue = {
|
|
467
|
+
message: string;
|
|
468
|
+
path?: ReadonlyArray<PropertyKey>;
|
|
469
|
+
};
|
|
470
|
+
type StandardSchemaResult = {
|
|
471
|
+
value: unknown;
|
|
472
|
+
issues?: undefined;
|
|
473
|
+
} | {
|
|
474
|
+
issues: ReadonlyArray<StandardSchemaIssue>;
|
|
475
|
+
value?: undefined;
|
|
476
|
+
};
|
|
477
|
+
/** SchemaNode 同步校验(生成模块与测试共用语义)。 */
|
|
478
|
+
declare function validateSchemaNode(node: SchemaNode, value: unknown): StandardSchemaResult;
|
|
479
|
+
type StandardSchemaModuleProjection = {
|
|
480
|
+
source: string;
|
|
481
|
+
dropped: string[];
|
|
482
|
+
};
|
|
483
|
+
/**
|
|
484
|
+
* Abs → Standard Schema v1 模块源码。
|
|
485
|
+
* `exports`:导出名 → Abs(通常是 output / 各参数)。
|
|
486
|
+
*/
|
|
487
|
+
declare function absToStandardSchemaModule(exports: Record<string, Abs>, opts?: {
|
|
488
|
+
banner?: string;
|
|
489
|
+
}): StandardSchemaModuleProjection;
|
|
490
|
+
/** 便捷:单个 Abs → 单导出模块(默认导出名 `schema`)。 */
|
|
491
|
+
declare function absToStandardSchema(a: Abs, opts?: {
|
|
492
|
+
name?: string;
|
|
493
|
+
}): StandardSchemaModuleProjection;
|
|
494
|
+
|
|
495
|
+
/** Abs 指称守卫(设计 §2.7):保留 pred */
|
|
496
|
+
declare function generateGuardFunctionFromAbs(name: string, abs: Abs): string;
|
|
497
|
+
/** 兼容别名:Abs 路径唯一 */
|
|
498
|
+
declare function generateGuardFunction(name: string, abs: Abs): string;
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Case facts JSON(`nudo test --json` 序列化)。
|
|
502
|
+
*
|
|
503
|
+
* - args / result / throws / combined:formatShape 外延投影(有损)
|
|
504
|
+
* 入口无约束参数展示为 any;unknown 仅表示推导失败
|
|
505
|
+
* - intension.abs*:无损 Abs 展示(主线)
|
|
506
|
+
* - argsAbs / resultAbs:CaseResult 上的无损 Abs(formatAbs);有则补齐
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
type CaseJsonCase = {
|
|
510
|
+
name: string;
|
|
511
|
+
/** formatShape 外延投影(有损) */
|
|
512
|
+
args: string[];
|
|
513
|
+
result: string;
|
|
514
|
+
throws: string | null;
|
|
515
|
+
source: string | null;
|
|
516
|
+
aggregatedFrom?: number;
|
|
517
|
+
/** 无损参数 Abs 展示(与 args 对齐;缺失位省略) */
|
|
518
|
+
argsAbs?: string[];
|
|
519
|
+
/** 无损结果 Abs 展示 */
|
|
520
|
+
resultAbs?: string;
|
|
521
|
+
/** 无损内涵(Abs);无则省略 */
|
|
522
|
+
intension?: {
|
|
523
|
+
display?: string;
|
|
524
|
+
abs?: string;
|
|
525
|
+
absMultiline?: string;
|
|
526
|
+
term?: string;
|
|
527
|
+
pred?: string;
|
|
528
|
+
conf?: string;
|
|
529
|
+
};
|
|
530
|
+
};
|
|
531
|
+
type CaseJsonFunction = {
|
|
532
|
+
name: string;
|
|
533
|
+
loc: SourceLocation;
|
|
534
|
+
entryOnly: boolean;
|
|
535
|
+
noDeclaration?: boolean;
|
|
536
|
+
cases: CaseJsonCase[];
|
|
537
|
+
combined?: string;
|
|
538
|
+
/** 无损 combined Abs 展示 */
|
|
539
|
+
combinedAbs?: string;
|
|
540
|
+
};
|
|
541
|
+
type CaseJson = {
|
|
542
|
+
version: 1;
|
|
543
|
+
file: string;
|
|
544
|
+
summary: {
|
|
545
|
+
functions: number;
|
|
546
|
+
externalFunctions: number;
|
|
547
|
+
cases: number;
|
|
548
|
+
diagnostics: number;
|
|
549
|
+
};
|
|
550
|
+
functions: CaseJsonFunction[];
|
|
551
|
+
externalFunctions?: Array<{
|
|
552
|
+
name: string;
|
|
553
|
+
fromModule?: string;
|
|
554
|
+
cases: CaseJsonCase[];
|
|
555
|
+
}>;
|
|
556
|
+
diagnostics: Array<{
|
|
557
|
+
range: SourceLocation;
|
|
558
|
+
severity: string;
|
|
559
|
+
message: string;
|
|
560
|
+
code?: string;
|
|
561
|
+
suggestions?: string[];
|
|
562
|
+
tags?: string[];
|
|
563
|
+
origin?: {
|
|
564
|
+
line: number;
|
|
565
|
+
column: number;
|
|
566
|
+
};
|
|
567
|
+
}>;
|
|
568
|
+
};
|
|
569
|
+
declare function serializeCaseJson(result: AnalysisResult, file: string): CaseJson;
|
|
570
|
+
|
|
571
|
+
/** 单个 Abs → parseCaseArgExpr 可解析回去的表达式文本;不可表达返回 null */
|
|
572
|
+
declare function serializeCaseArg(a: Abs): string | null;
|
|
573
|
+
/**
|
|
574
|
+
* 组装单行 ` * @nudo:case "name" (a, b)` 指令文本(无尾换行)。
|
|
575
|
+
* 任一实参不可序列化、或名字含双引号/换行(名字正则 `"([^"]+)"` 承载不了)→ 整体 null。
|
|
576
|
+
*/
|
|
577
|
+
declare function buildCaseDirective(name: string, argsAbs: Abs[]): string | null;
|
|
578
|
+
/**
|
|
579
|
+
* 从源码剥离所有本模块生成的 @nudo:case 指令(名字以 call@ 开头,整行删除)。
|
|
580
|
+
* 若所属 JSDoc 块因此只剩空 ` *` 行(无其他 @nudo:* 指令、无文字内容),
|
|
581
|
+
* 连块首 `/**` 行与块尾行整块删除。绝不碰非 case 指令与普通注释。
|
|
582
|
+
* 注意:手写但以 call@ 命名的 case 同样会被删——call@ 前缀保留为生成物标记。
|
|
583
|
+
* removed 返回被删指令名列表(按出现顺序)。
|
|
584
|
+
*/
|
|
585
|
+
declare function stripGeneratedCaseDirectives(source: string): {
|
|
586
|
+
source: string;
|
|
587
|
+
removed: string[];
|
|
588
|
+
};
|
|
589
|
+
type EmitSkipReason = "hand-written" | "already-generated" | "entry-only" | "no-serializable-cases" | "no-declaration" | "skipped";
|
|
590
|
+
type EmitResult = {
|
|
591
|
+
source: string;
|
|
592
|
+
changed: boolean;
|
|
593
|
+
written: Array<{
|
|
594
|
+
fn: string;
|
|
595
|
+
cases: string[];
|
|
596
|
+
}>;
|
|
597
|
+
skipped: Array<{
|
|
598
|
+
fn: string;
|
|
599
|
+
reason: EmitSkipReason;
|
|
600
|
+
detail?: string;
|
|
601
|
+
}>;
|
|
602
|
+
};
|
|
603
|
+
/**
|
|
604
|
+
* 把 analysis 中的合成 case(source === "callsite")固化为源码指令:
|
|
605
|
+
*
|
|
606
|
+
* 1. 源码已有任何非 call@ 命名的 case → skip "hand-written";
|
|
607
|
+
* 已有 call@ case → skip "already-generated"。
|
|
608
|
+
* 2. fn.skipped / fn.noDeclaration / fn.entryOnly → 对应 skip。
|
|
609
|
+
* 3. 逐 case 序列化;个别不可序列化的丢弃并在 skipped 记
|
|
610
|
+
* no-serializable-cases(函数整体仍写可序列化子集,全不可序列化才整函数跳过)。
|
|
611
|
+
* 4. 写入位置:函数声明行正上方——已有 JSDoc 块则插到 `/**` 行后,
|
|
612
|
+
* 无块则新建三行块。缩进取声明行的 loc.start.column(babel 0 基列)。
|
|
613
|
+
* 多函数编辑按行号从下往上应用,避免行号漂移。
|
|
614
|
+
*/
|
|
615
|
+
declare function insertGeneratedCaseDirectives(source: string, analysis: AnalysisResult): EmitResult;
|
|
616
|
+
/** 行级 unified diff:`--- a/path` 头 + `@@` hunk + 上下文 3 行;相同返回 "" */
|
|
617
|
+
declare function unifiedDiff(a: string, b: string, path: string): string;
|
|
618
|
+
|
|
619
|
+
export { type CaseJson, type CaseJsonCase, type CaseJsonFunction, type ConstraintSourceExpr, type DerivedExport, type DerivedParam, type DraftEvidence, type EmitDerivedResult, type EmitInterfaceOpts, type EmitInterfaceResult, type EmitInterfaceSkipReason, type EmitResult, type EmitSkipReason, type InterfaceDraftEntry, type InterfaceDraftOpts, type InterfaceDraftResult, type InterfaceSurfaceEntry, type InterfaceSurfaceOpts, type RootDeriveOpts, type RootDeriveResult, type SchemaDialect, type SchemaNode, type SchemaProjection, type SchemaRefinement, type StandardSchemaIssue, type StandardSchemaModuleProjection, type StandardSchemaResult, type WriteDraftResult, type ZodModuleProjection, absToSchemaNode, absToSchemaSource, absToStandardSchema, absToStandardSchemaModule, absToTSType, absToZodSchemaModule, buildCaseDirective, collectParamBodyAccesses, constraintToSchemaNode, deriveFromRoot, draftInterface, emitDerivedFromRoot, emitInterface, extractFnConstraintSources, formatDerivedSection, formatDraftModule, formatDraftSummary, formatEmitSummary, formatInterfaceSurfaceLine, generateDts, generateFunctionDtsLines, generateGuardFunction, generateGuardFunctionFromAbs, insertGeneratedCaseDirectives, interfaceSurface, isDraftableEntry, projectAbsToSchema, schemaNodeToZod, serializeCaseArg, serializeCaseJson, sidecarDraftPath, stripGeneratedCaseDirectives, unifiedDiff, validateSchemaNode, writeInterfaceDraft };
|