@longzai-intelligence-pendings-markdown/core 0.0.0-stage → 0.0.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 +10 -2
- package/dist/index.d.ts +654 -0
- package/dist/index.js +12 -0
- package/dist/rolldown-runtime-BqT_7tdF.js +1 -0
- package/package.json +46 -4
package/README.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @longzai-intelligence-pendings-markdown/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
投影转换引擎。
|
|
4
|
+
|
|
5
|
+
## 职责
|
|
6
|
+
|
|
7
|
+
- 源读取即 `loadPendingSource`,扫描 data-home 下 `pendings` 年月目录的待裁档,声明方言解析规格与 pendings 仓 core 同源零跨仓依赖自实现,结构级轻量契约校验后违规档跳过并逐档携带违规清单
|
|
8
|
+
- 渲染器族即投影档、月目录 README、总目录册、数据根 README 骨架,元数据一律随 frontmatter,正文哈希作幂等键
|
|
9
|
+
- 仓库服务即月目录写入器与数据根目录册管理器,机制经 markdown 家族 data-engine 的分区写入器与目录册服务承载,只写盘不提交
|
|
10
|
+
- 运行时环境解析即配置文件必备承载 `dataRoot` 加环境变量承载源台账路径的域侧组合
|
|
11
|
+
- 用例编排即 `runConvert` 转换与 `runVerify` 体检,全程幂等,体检只报告不阻断
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
import "./rolldown-runtime-BqT_7tdF.js";
|
|
2
|
+
import { CatalogRefreshOptions, CatalogRefreshResult as CatalogRefreshResult$1, PartitionWriteResult, RenderedDocument } from "@longzai-intelligence-markdown/data-engine";
|
|
3
|
+
import { ConfigLoadError } from "@longzai-intelligence-pendings-markdown/config";
|
|
4
|
+
/**
|
|
5
|
+
* 源台账只读适配器
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* 扫描 data-home 下 `pendings` 月份目录中的待裁档,按声明方言解析并做结构
|
|
9
|
+
* 级轻量契约校验,违规档不阻断扫描逐档携带违规清单供 convert 报告消费。
|
|
10
|
+
* 跨字段约束正本归 pendings 仓 config 包 schema,本层只做投影所需的结构
|
|
11
|
+
* 级校验即必填字段与枚举与日期格式与 id 文件名一致性
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* 源待裁档字段值形态即标量或字符串数组
|
|
15
|
+
*/
|
|
16
|
+
type SourceFieldValue = string | readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* 投影条目即校验通过的源待裁档投影输入
|
|
19
|
+
*/
|
|
20
|
+
type PendingDocProjection = {
|
|
21
|
+
/**
|
|
22
|
+
* 待裁项 slug 即文件名主干
|
|
23
|
+
*/
|
|
24
|
+
readonly slug: string;
|
|
25
|
+
/**
|
|
26
|
+
* 提出年月目录名即 `raised` 的年月段
|
|
27
|
+
*/
|
|
28
|
+
readonly month: string;
|
|
29
|
+
/**
|
|
30
|
+
* 源 frontmatter 全字段即标量与数组合并形态
|
|
31
|
+
*/
|
|
32
|
+
readonly fields: Readonly<Record<string, SourceFieldValue>>;
|
|
33
|
+
/**
|
|
34
|
+
* 正文全文
|
|
35
|
+
*/
|
|
36
|
+
readonly body: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* 源档违规条目
|
|
40
|
+
*/
|
|
41
|
+
type SourceViolation = {
|
|
42
|
+
/**
|
|
43
|
+
* 违规档相对 data-home 路径
|
|
44
|
+
*/
|
|
45
|
+
readonly relativePath: string;
|
|
46
|
+
/**
|
|
47
|
+
* 违规消息清单
|
|
48
|
+
*/
|
|
49
|
+
readonly violations: readonly string[];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* 源台账全量读取结果
|
|
53
|
+
*/
|
|
54
|
+
type PendingSourceSnapshot = {
|
|
55
|
+
/**
|
|
56
|
+
* 校验通过的投影条目,按年月与 slug 排序
|
|
57
|
+
*/
|
|
58
|
+
readonly docs: readonly PendingDocProjection[];
|
|
59
|
+
/**
|
|
60
|
+
* 违规档清单
|
|
61
|
+
*/
|
|
62
|
+
readonly violations: readonly SourceViolation[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 读取源台账全量快照
|
|
66
|
+
*
|
|
67
|
+
* @param sourceHome - 源台账 data-home 绝对路径
|
|
68
|
+
* @returns 投影条目与违规档清单,目录缺失时为空快照不报错
|
|
69
|
+
*/
|
|
70
|
+
declare function loadPendingSource(sourceHome: string): PendingSourceSnapshot;
|
|
71
|
+
/**
|
|
72
|
+
* 投影渲染器族即条目档与月目录 README 与总目录册与数据根 README
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* 渲染产物统一为 RenderedDocument 即全文加正文幂等哈希,元数据一律随
|
|
76
|
+
* frontmatter 禁 JSON 文件,管线标准字段经 `pipelineFrontmatter` 构造
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* 投影档文件名
|
|
80
|
+
*
|
|
81
|
+
* @param slug - 待裁项 slug
|
|
82
|
+
* @returns 文件名即 slug 加 `.pending.md` 后缀
|
|
83
|
+
*/
|
|
84
|
+
declare function pendingDocFileName(slug: string): string;
|
|
85
|
+
/**
|
|
86
|
+
* 渲染单篇投影档
|
|
87
|
+
*
|
|
88
|
+
* @remarks
|
|
89
|
+
* frontmatter 为管线标准字段加源档全字段,正文为源档正文原样投影,哈希
|
|
90
|
+
* 仅覆盖正文
|
|
91
|
+
* @param entry - 投影条目
|
|
92
|
+
* @param generatedAt - 生成时刻即 ISO8601 白名单字段不参与哈希
|
|
93
|
+
* @returns 完整投影档文档与正文哈希
|
|
94
|
+
*/
|
|
95
|
+
declare function renderPendingDocument(entry: PendingDocProjection, generatedAt: string): RenderedDocument;
|
|
96
|
+
/**
|
|
97
|
+
* 渲染月目录 README 即当月概览与档索引表
|
|
98
|
+
*
|
|
99
|
+
* @param month - 年月目录名
|
|
100
|
+
* @param entries - 该月投影条目即排序后序列
|
|
101
|
+
* @param generatedAt - 生成时刻
|
|
102
|
+
* @returns 完整 README 文档与正文哈希
|
|
103
|
+
*/
|
|
104
|
+
declare function renderMonthReadme(month: string, entries: readonly PendingDocProjection[], generatedAt: string): RenderedDocument;
|
|
105
|
+
/**
|
|
106
|
+
* 目录册条目即磁盘扫描产出
|
|
107
|
+
*/
|
|
108
|
+
type CatalogEntry = {
|
|
109
|
+
/**
|
|
110
|
+
* 年月目录名即表行键
|
|
111
|
+
*/
|
|
112
|
+
readonly month: string;
|
|
113
|
+
/**
|
|
114
|
+
* 该月投影档数
|
|
115
|
+
*/
|
|
116
|
+
readonly docCount: number;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* 月目录相对数据根路径
|
|
120
|
+
*
|
|
121
|
+
* @param month - 年月目录名
|
|
122
|
+
* @returns 相对路径
|
|
123
|
+
*/
|
|
124
|
+
declare function monthRelDir(month: string): string;
|
|
125
|
+
/**
|
|
126
|
+
* 渲染总目录册
|
|
127
|
+
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* 总目录册为全部月目录的索引表即跨目录检索与统计的唯一汇总面,哈希仅覆
|
|
130
|
+
* 盖正文
|
|
131
|
+
* @param entries - 目录册条目升序
|
|
132
|
+
* @param generatedAt - 生成时刻
|
|
133
|
+
* @returns 完整目录册文档与正文哈希
|
|
134
|
+
*/
|
|
135
|
+
declare function renderCatalog(entries: readonly CatalogEntry[], generatedAt: string): RenderedDocument;
|
|
136
|
+
/**
|
|
137
|
+
* 渲染数据根 README 骨架即数据区说明,仅缺失时写入不参与幂等覆盖
|
|
138
|
+
*
|
|
139
|
+
* @returns 数据根 README 全文
|
|
140
|
+
*/
|
|
141
|
+
declare function renderDataRootReadme(): string;
|
|
142
|
+
/**
|
|
143
|
+
* 数据根目录册管理器
|
|
144
|
+
*
|
|
145
|
+
* @remarks
|
|
146
|
+
* 跟踪根 `README.md` 与 `catalog.md` 与 `.gitignore` 骨架及 `pendings/` 数
|
|
147
|
+
* 据父目录,扫描磁盘月目录产出目录册条目并重建或增量更新目录册。机制即
|
|
148
|
+
* 幂等写与骨架补齐与对账由引擎 CatalogService 承载,本类只做域 profile
|
|
149
|
+
* 装配,只写盘不提交见本仓决策 0001
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* 管理器构造项
|
|
153
|
+
*/
|
|
154
|
+
type CatalogServiceOptions = {
|
|
155
|
+
/**
|
|
156
|
+
* 数据根绝对路径
|
|
157
|
+
*/
|
|
158
|
+
readonly dataRoot: string;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* 刷新行为开关
|
|
162
|
+
*/
|
|
163
|
+
type RefreshOptions = CatalogRefreshOptions;
|
|
164
|
+
/**
|
|
165
|
+
* 刷新结果
|
|
166
|
+
*/
|
|
167
|
+
type CatalogRefreshResult = CatalogRefreshResult$1<CatalogEntry>;
|
|
168
|
+
/**
|
|
169
|
+
* 目录册管理器即引擎服务委托
|
|
170
|
+
*/
|
|
171
|
+
declare class CatalogService {
|
|
172
|
+
/**
|
|
173
|
+
* 数据根绝对路径
|
|
174
|
+
*/
|
|
175
|
+
readonly dataRoot: string;
|
|
176
|
+
/**
|
|
177
|
+
* 引擎目录册服务实例
|
|
178
|
+
*/
|
|
179
|
+
private readonly service;
|
|
180
|
+
/**
|
|
181
|
+
* 构造管理器
|
|
182
|
+
*
|
|
183
|
+
* @param options - 构造项即 dataRoot 必填
|
|
184
|
+
* @returns 管理器实例
|
|
185
|
+
*/
|
|
186
|
+
constructor(options: CatalogServiceOptions);
|
|
187
|
+
/**
|
|
188
|
+
* 扫描磁盘月目录
|
|
189
|
+
*
|
|
190
|
+
* @returns 目录册条目列表升序
|
|
191
|
+
*/
|
|
192
|
+
scan(): Promise<readonly CatalogEntry[]>;
|
|
193
|
+
/**
|
|
194
|
+
* 确保数据根就绪即目录与 git 仓与骨架文件
|
|
195
|
+
*
|
|
196
|
+
* @param dryRun - 干跑时不做任何落盘
|
|
197
|
+
* @returns 本次新建的根文件相对路径清单
|
|
198
|
+
*/
|
|
199
|
+
ensureRoot(dryRun: boolean): Promise<readonly string[]>;
|
|
200
|
+
/**
|
|
201
|
+
* 刷新目录册即扫描后与现存目录册比对变更才写盘
|
|
202
|
+
*
|
|
203
|
+
* @param options - 行为开关即 dryRun
|
|
204
|
+
* @returns 刷新结果
|
|
205
|
+
*/
|
|
206
|
+
refresh(options?: RefreshOptions): Promise<CatalogRefreshResult>;
|
|
207
|
+
/**
|
|
208
|
+
* 对账现存目录册与磁盘实测即只报告不修复
|
|
209
|
+
*
|
|
210
|
+
* @returns 问题清单,空即对账通过
|
|
211
|
+
*/
|
|
212
|
+
check(): Promise<readonly string[]>;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* 源台账 data-home 环境变量名
|
|
216
|
+
*/
|
|
217
|
+
declare const ENV_SOURCE_HOME = "LZI_PENDINGS_DATA_HOME";
|
|
218
|
+
/**
|
|
219
|
+
* 解析后的环境配置即绝对路径形态
|
|
220
|
+
*/
|
|
221
|
+
type PendingsMarkdownEnv = {
|
|
222
|
+
/**
|
|
223
|
+
* 源台账 data-home 绝对路径,只读消费
|
|
224
|
+
*/
|
|
225
|
+
readonly sourceHome: string;
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* 环境配置错误即缺失或非法附缺失变量名清单,引擎 EnvError 形态
|
|
229
|
+
*/
|
|
230
|
+
type EnvError = {
|
|
231
|
+
/**
|
|
232
|
+
* 错误码
|
|
233
|
+
*/
|
|
234
|
+
readonly code: 'ENV_INVALID';
|
|
235
|
+
/**
|
|
236
|
+
* 人读错误信息
|
|
237
|
+
*/
|
|
238
|
+
readonly message: string;
|
|
239
|
+
/**
|
|
240
|
+
* 缺失或非法的变量名清单
|
|
241
|
+
*/
|
|
242
|
+
readonly missing: readonly string[];
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* 域环境工具族实例即变量声明与装配语义,机制由引擎承载
|
|
246
|
+
*/
|
|
247
|
+
declare const envKit: import("@longzai-intelligence-markdown/data-engine").EnvKit<PendingsMarkdownEnv>;
|
|
248
|
+
/**
|
|
249
|
+
* 从进程环境解析配置即 zod 校验加绝对路径化
|
|
250
|
+
*
|
|
251
|
+
* @param processEnv - 进程环境,缺省取 `process.env`,测试可注入
|
|
252
|
+
* @returns 解析成功为绝对路径形态 env,失败为缺失变量清单错误
|
|
253
|
+
*/
|
|
254
|
+
declare function resolveEnv(processEnv?: NodeJS.ProcessEnv): ReturnType<typeof envKit.resolveEnv>;
|
|
255
|
+
/**
|
|
256
|
+
* 供模板渲染消费的域工具族实例
|
|
257
|
+
*/
|
|
258
|
+
declare const pendingsMarkdownEnvKit: import("@longzai-intelligence-markdown/data-engine").EnvKit<PendingsMarkdownEnv>;
|
|
259
|
+
/**
|
|
260
|
+
* 运行时环境解析即配置文件必备加 env 字段级分工
|
|
261
|
+
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* 通道分工沿家族配方见全局 ADR 0097 决策 5 与 9:配置文件承载 `dataRoot`
|
|
264
|
+
* 且必备,环境变量承载源台账 data-home 即 `LZI_PENDINGS_DATA_HOME`,配置
|
|
265
|
+
* 文件未找到即报错不作整体 env 替代,域侧组合实现
|
|
266
|
+
*/
|
|
267
|
+
/**
|
|
268
|
+
* 解析命中通道
|
|
269
|
+
*/
|
|
270
|
+
type RuntimeEnvChannel = 'config-file';
|
|
271
|
+
/**
|
|
272
|
+
* 运行时环境即合并形态
|
|
273
|
+
*/
|
|
274
|
+
type RuntimeEnv = {
|
|
275
|
+
/**
|
|
276
|
+
* 数据根绝对路径由配置文件承载,就地自指以文件所在目录绝对化
|
|
277
|
+
*/
|
|
278
|
+
readonly dataRoot: string;
|
|
279
|
+
/**
|
|
280
|
+
* 源台账 data-home 绝对路径由环境变量承载,只读消费
|
|
281
|
+
*/
|
|
282
|
+
readonly sourceHome: string;
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* 解析成功结果
|
|
286
|
+
*/
|
|
287
|
+
type RuntimeEnvResolution = {
|
|
288
|
+
/**
|
|
289
|
+
* 命中通道恒为配置文件即必备后无整体 env 通道
|
|
290
|
+
*/
|
|
291
|
+
readonly channel: RuntimeEnvChannel;
|
|
292
|
+
/**
|
|
293
|
+
* 合并后的运行时环境
|
|
294
|
+
*/
|
|
295
|
+
readonly env: RuntimeEnv;
|
|
296
|
+
/**
|
|
297
|
+
* 命中的配置文件绝对路径
|
|
298
|
+
*/
|
|
299
|
+
readonly configPath: string;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* 解析错误即配置文件缺失或非法与环境变量缺失
|
|
303
|
+
*/
|
|
304
|
+
type RuntimeEnvError = ConfigLoadError | EnvError;
|
|
305
|
+
/**
|
|
306
|
+
* 解析结果
|
|
307
|
+
*/
|
|
308
|
+
type RuntimeEnvResult = {
|
|
309
|
+
readonly ok: true;
|
|
310
|
+
readonly value: RuntimeEnvResolution;
|
|
311
|
+
} | {
|
|
312
|
+
readonly ok: false;
|
|
313
|
+
readonly error: RuntimeEnvError;
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* 解析运行时环境即配置文件必备加源路径 env 字段级合并
|
|
317
|
+
*
|
|
318
|
+
* @param explicitConfigPath - 显式配置文件路径可选,缺省自当前目录向上发现
|
|
319
|
+
* @returns 成功为合并形态运行时环境与配置文件路径,失败为可读错误
|
|
320
|
+
*/
|
|
321
|
+
declare function resolveRuntimeEnv(explicitConfigPath?: string): Promise<RuntimeEnvResult>;
|
|
322
|
+
/**
|
|
323
|
+
* 轻量 Result 类型
|
|
324
|
+
*
|
|
325
|
+
* @remarks
|
|
326
|
+
* 可预期失败走 Result 返回不抛异常穿透编排层边界,形态与 markdown 家族
|
|
327
|
+
* data-engine 的 Result 约定同源,本包自持定义以保持零引擎类型耦合
|
|
328
|
+
*/
|
|
329
|
+
/**
|
|
330
|
+
* 成功分支携带值
|
|
331
|
+
*
|
|
332
|
+
* @typeParam TValue - 成功分支携带值的类型
|
|
333
|
+
*/
|
|
334
|
+
type ResultOk<TValue> = {
|
|
335
|
+
/**
|
|
336
|
+
* 判别标记即成功
|
|
337
|
+
*/
|
|
338
|
+
readonly ok: true;
|
|
339
|
+
/**
|
|
340
|
+
* 成功携带值
|
|
341
|
+
*/
|
|
342
|
+
readonly value: TValue;
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* 失败分支携带错误
|
|
346
|
+
*
|
|
347
|
+
* @typeParam TError - 失败分支携带错误的类型
|
|
348
|
+
*/
|
|
349
|
+
type ResultErr<TError> = {
|
|
350
|
+
/**
|
|
351
|
+
* 判别标记即失败
|
|
352
|
+
*/
|
|
353
|
+
readonly ok: false;
|
|
354
|
+
/**
|
|
355
|
+
* 失败携带错误
|
|
356
|
+
*/
|
|
357
|
+
readonly error: TError;
|
|
358
|
+
};
|
|
359
|
+
/**
|
|
360
|
+
* 轻量 Result 判别联合即可预期失败的显式返回通道
|
|
361
|
+
*
|
|
362
|
+
* @typeParam TValue - 成功分支携带值的类型
|
|
363
|
+
* @typeParam TError - 失败分支携带错误的类型
|
|
364
|
+
*/
|
|
365
|
+
type Result<TValue, TError> = ResultOk<TValue> | ResultErr<TError>;
|
|
366
|
+
/**
|
|
367
|
+
* 成功结果构造器
|
|
368
|
+
*
|
|
369
|
+
* @typeParam TValue - 成功携带值类型
|
|
370
|
+
* @param value - 成功携带值
|
|
371
|
+
* @returns 成功分支 Result
|
|
372
|
+
*/
|
|
373
|
+
declare function success<TValue>(value: TValue): Result<TValue, never>;
|
|
374
|
+
/**
|
|
375
|
+
* 失败结果构造器
|
|
376
|
+
*
|
|
377
|
+
* @typeParam TError - 失败携带错误类型
|
|
378
|
+
* @param error - 失败携带错误
|
|
379
|
+
* @returns 失败分支 Result
|
|
380
|
+
*/
|
|
381
|
+
declare function failure<TError>(error: TError): Result<never, TError>;
|
|
382
|
+
/**
|
|
383
|
+
* convert 编排门面
|
|
384
|
+
*
|
|
385
|
+
* @remarks
|
|
386
|
+
* 主流程为解析选择器即 `--month` 与 `--all` 二选一,读源台账快照,逐月写
|
|
387
|
+
* 入投影档与月目录 README,刷新数据根目录册。全程幂等即零变更零写入,只
|
|
388
|
+
* 写盘不提交提交由人执行见本仓决策 0001,违规源档跳过并逐档列入报告
|
|
389
|
+
*/
|
|
390
|
+
/**
|
|
391
|
+
* 转换选择器
|
|
392
|
+
*/
|
|
393
|
+
type ConvertSelection = {
|
|
394
|
+
/**
|
|
395
|
+
* 单月即 `YYYY-MM`
|
|
396
|
+
*/
|
|
397
|
+
readonly month?: string;
|
|
398
|
+
/**
|
|
399
|
+
* 全量即源台账内全部年月
|
|
400
|
+
*/
|
|
401
|
+
readonly all?: boolean;
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* 转换行为开关
|
|
405
|
+
*/
|
|
406
|
+
type ConvertOptions = ConvertSelection & {
|
|
407
|
+
/**
|
|
408
|
+
* 干跑即零落盘
|
|
409
|
+
*/
|
|
410
|
+
readonly dryRun?: boolean;
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* 单月转换报告
|
|
414
|
+
*/
|
|
415
|
+
type ConvertMonthReport = {
|
|
416
|
+
/**
|
|
417
|
+
* 年月目录名
|
|
418
|
+
*/
|
|
419
|
+
readonly month: string;
|
|
420
|
+
/**
|
|
421
|
+
* 源台账该月合规档数
|
|
422
|
+
*/
|
|
423
|
+
readonly docs: number;
|
|
424
|
+
/**
|
|
425
|
+
* 写入文档数含 README
|
|
426
|
+
*/
|
|
427
|
+
readonly written: number;
|
|
428
|
+
/**
|
|
429
|
+
* 幂等跳过文档数含 README
|
|
430
|
+
*/
|
|
431
|
+
readonly skipped: number;
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* 转换总报告
|
|
435
|
+
*/
|
|
436
|
+
type ConvertReport = {
|
|
437
|
+
/**
|
|
438
|
+
* 逐月报告升序
|
|
439
|
+
*/
|
|
440
|
+
readonly months: readonly ConvertMonthReport[];
|
|
441
|
+
/**
|
|
442
|
+
* 源档违规清单即跳过档
|
|
443
|
+
*/
|
|
444
|
+
readonly violations: readonly SourceViolation[];
|
|
445
|
+
/**
|
|
446
|
+
* 目录册刷新结果
|
|
447
|
+
*/
|
|
448
|
+
readonly catalog: CatalogRefreshResult;
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* 转换编排错误
|
|
452
|
+
*/
|
|
453
|
+
type ConvertError = {
|
|
454
|
+
/**
|
|
455
|
+
* 错误码
|
|
456
|
+
*/
|
|
457
|
+
readonly code: 'SELECTION_INVALID' | 'MONTH_INVALID';
|
|
458
|
+
/**
|
|
459
|
+
* 人读错误信息
|
|
460
|
+
*/
|
|
461
|
+
readonly message: string;
|
|
462
|
+
};
|
|
463
|
+
/**
|
|
464
|
+
* 执行转换即编排门面
|
|
465
|
+
*
|
|
466
|
+
* @param env - 解析后的运行时环境
|
|
467
|
+
* @param options - 选择器与行为开关
|
|
468
|
+
* @returns 转换总报告,失败为选择器错误
|
|
469
|
+
*/
|
|
470
|
+
declare function runConvert(env: RuntimeEnv, options: ConvertOptions): Promise<Result<ConvertReport, ConvertError>>;
|
|
471
|
+
/**
|
|
472
|
+
* 声明档 frontmatter 方言解析器
|
|
473
|
+
*
|
|
474
|
+
* @remarks
|
|
475
|
+
* 方言为顶层标量与字符串数组,规格与 pendings 仓 core 的 `parseDeclaration`
|
|
476
|
+
* 同源,本包零跨仓依赖自实现且只实现读取侧,投影写侧走引擎序列化。源档由
|
|
477
|
+
* `lzi-pendings` 写入,本解析器按其确定性输出形态读取,单测锁定行为
|
|
478
|
+
*/
|
|
479
|
+
/**
|
|
480
|
+
* 声明档解析结果
|
|
481
|
+
*/
|
|
482
|
+
type ParsedDeclaration = {
|
|
483
|
+
/**
|
|
484
|
+
* 顶层标量键值
|
|
485
|
+
*/
|
|
486
|
+
readonly head: Record<string, string>;
|
|
487
|
+
/**
|
|
488
|
+
* 字符串数组键值
|
|
489
|
+
*/
|
|
490
|
+
readonly arrays: Record<string, readonly string[]>;
|
|
491
|
+
/**
|
|
492
|
+
* 正文全文
|
|
493
|
+
*/
|
|
494
|
+
readonly body: string;
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* 解析声明档
|
|
498
|
+
*
|
|
499
|
+
* @param documentText - 文档全文
|
|
500
|
+
* @returns 解析结果,无 frontmatter 时 head 与 arrays 为空对象且 body 为全文
|
|
501
|
+
*/
|
|
502
|
+
declare const parseDeclaration: (documentText: string) => ParsedDeclaration;
|
|
503
|
+
/**
|
|
504
|
+
* frontmatter 引号归一器
|
|
505
|
+
*
|
|
506
|
+
* @remarks
|
|
507
|
+
* 引擎序列化 YAML 值默认双引号并对内部双引号反斜杠转义,格式化器按转义
|
|
508
|
+
* 次数择形即单双引号谁需要更少转义用谁平手取单。渲染层先行归一为同款
|
|
509
|
+
* 形态达成渲染产物字节稳定,规格与 arxiv-markdown 仓同名工具同源本包自
|
|
510
|
+
* 持实现
|
|
511
|
+
*/
|
|
512
|
+
/**
|
|
513
|
+
* 归一 frontmatter 文本中的双引号值为格式化器同款引号形态
|
|
514
|
+
*
|
|
515
|
+
* @remarks
|
|
516
|
+
* 值内转义先行还原,再按双引号与反斜杠合计转义次数对单引号转义次数比
|
|
517
|
+
* 较择形即双形态更少转义取双否则取单
|
|
518
|
+
* @param frontmatterText - 引擎序列化的 frontmatter 文本
|
|
519
|
+
* @returns 归一后的 frontmatter 文本
|
|
520
|
+
*/
|
|
521
|
+
declare function normalizeFrontmatterQuotes(frontmatterText: string): string;
|
|
522
|
+
/**
|
|
523
|
+
* 确定性对齐表格渲染器
|
|
524
|
+
*
|
|
525
|
+
* @remarks
|
|
526
|
+
* 按列宽全角对齐渲染 markdown 表格,列宽取表头与各行列值的最大显示宽度,
|
|
527
|
+
* 同源输入产出字节稳定输出供目录册与月目录 README 消费
|
|
528
|
+
*/
|
|
529
|
+
/**
|
|
530
|
+
* 渲染对齐表格
|
|
531
|
+
*
|
|
532
|
+
* @param headers - 表头序列
|
|
533
|
+
* @param rows - 行序列即各行列值序列
|
|
534
|
+
* @returns 表格文本行序列
|
|
535
|
+
*/
|
|
536
|
+
declare function renderAlignedTable(headers: readonly string[], rows: readonly (readonly string[])[]): string[];
|
|
537
|
+
/**
|
|
538
|
+
* 月目录写入器即数据根下 `pendings` 年月目录
|
|
539
|
+
*
|
|
540
|
+
* @remarks
|
|
541
|
+
* 职责为确保月目录存在后写入投影档与 README,写入经引擎 PartitionWriter
|
|
542
|
+
* 的 P2 分区零 git 形态承载即临时文件加改名原子写与 `content_hash` 幂等
|
|
543
|
+
* 跳过,只写盘不提交,提交由人执行见本仓决策 0001
|
|
544
|
+
*/
|
|
545
|
+
/**
|
|
546
|
+
* 管理器构造项
|
|
547
|
+
*/
|
|
548
|
+
type MonthRepoServiceOptions = {
|
|
549
|
+
/**
|
|
550
|
+
* 数据根绝对路径
|
|
551
|
+
*/
|
|
552
|
+
readonly dataRoot: string;
|
|
553
|
+
};
|
|
554
|
+
/**
|
|
555
|
+
* 单月写入行为开关
|
|
556
|
+
*/
|
|
557
|
+
type WriteMonthOptions = {
|
|
558
|
+
/**
|
|
559
|
+
* 干跑即只计算不落盘
|
|
560
|
+
*/
|
|
561
|
+
readonly dryRun?: boolean;
|
|
562
|
+
};
|
|
563
|
+
/**
|
|
564
|
+
* 月目录写入器实例
|
|
565
|
+
*/
|
|
566
|
+
declare class MonthRepoService {
|
|
567
|
+
/**
|
|
568
|
+
* 数据根绝对路径
|
|
569
|
+
*/
|
|
570
|
+
readonly dataRoot: string;
|
|
571
|
+
/**
|
|
572
|
+
* 引擎分区写入器实例即 P2 分区零 git 形态
|
|
573
|
+
*/
|
|
574
|
+
private readonly writer;
|
|
575
|
+
/**
|
|
576
|
+
* 构造写入器
|
|
577
|
+
*
|
|
578
|
+
* @param options - 构造项即 dataRoot 必填
|
|
579
|
+
* @returns 写入器实例
|
|
580
|
+
*/
|
|
581
|
+
constructor(options: MonthRepoServiceOptions);
|
|
582
|
+
/**
|
|
583
|
+
* 写入单月即投影档加 README,幂等跳过,只写盘不提交
|
|
584
|
+
*
|
|
585
|
+
* @param month - 年月目录名即 `YYYY-MM`
|
|
586
|
+
* @param entries - 该月投影条目,内部按 slug 升序落盘
|
|
587
|
+
* @param options - 行为开关即 dryRun
|
|
588
|
+
* @returns 写入统计
|
|
589
|
+
*/
|
|
590
|
+
writeMonth(month: string, entries: readonly PendingDocProjection[], options?: WriteMonthOptions): Promise<PartitionWriteResult>;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* verify 编排门面
|
|
594
|
+
*
|
|
595
|
+
* @remarks
|
|
596
|
+
* 一致性体检只报告不阻断,三项检查为逐文档复算 `content_hash` 比对登记值、
|
|
597
|
+
* 月目录 README 档数登记与实测对账、目录册与磁盘月目录三方对账,另加跨
|
|
598
|
+
* 月重复 slug 检测即同一 slug 出现在多个月目录视为一致性问题
|
|
599
|
+
*/
|
|
600
|
+
/**
|
|
601
|
+
* 单文档哈希漂移
|
|
602
|
+
*/
|
|
603
|
+
type HashDrift = {
|
|
604
|
+
/**
|
|
605
|
+
* 文档绝对路径
|
|
606
|
+
*/
|
|
607
|
+
readonly file: string;
|
|
608
|
+
/**
|
|
609
|
+
* frontmatter 登记值,缺失为空
|
|
610
|
+
*/
|
|
611
|
+
readonly expected: string | null;
|
|
612
|
+
/**
|
|
613
|
+
* 正文复算值
|
|
614
|
+
*/
|
|
615
|
+
readonly actual: string;
|
|
616
|
+
};
|
|
617
|
+
/**
|
|
618
|
+
* 体检报告
|
|
619
|
+
*/
|
|
620
|
+
type VerifyReport = {
|
|
621
|
+
/**
|
|
622
|
+
* 哈希漂移清单,空即全部一致
|
|
623
|
+
*/
|
|
624
|
+
readonly hashDrifts: readonly HashDrift[];
|
|
625
|
+
/**
|
|
626
|
+
* 一致性问题清单
|
|
627
|
+
*/
|
|
628
|
+
readonly issues: readonly string[];
|
|
629
|
+
/**
|
|
630
|
+
* 是否全部通过
|
|
631
|
+
*/
|
|
632
|
+
readonly ok: boolean;
|
|
633
|
+
};
|
|
634
|
+
/**
|
|
635
|
+
* 数据根缺失错误
|
|
636
|
+
*/
|
|
637
|
+
type VerifyError = {
|
|
638
|
+
/**
|
|
639
|
+
* 错误码
|
|
640
|
+
*/
|
|
641
|
+
readonly code: 'DATA_ROOT_MISSING';
|
|
642
|
+
/**
|
|
643
|
+
* 人读错误信息
|
|
644
|
+
*/
|
|
645
|
+
readonly message: string;
|
|
646
|
+
};
|
|
647
|
+
/**
|
|
648
|
+
* 执行体检
|
|
649
|
+
*
|
|
650
|
+
* @param env - 解析后的运行时环境
|
|
651
|
+
* @returns 体检报告,数据根缺失为错误
|
|
652
|
+
*/
|
|
653
|
+
declare function runVerify(env: RuntimeEnv): Promise<Result<VerifyReport, VerifyError>>;
|
|
654
|
+
export { CatalogEntry, CatalogRefreshResult, CatalogService, CatalogServiceOptions, ConvertError, ConvertMonthReport, ConvertOptions, ConvertReport, ConvertSelection, ENV_SOURCE_HOME, EnvError, HashDrift, MonthRepoService, MonthRepoServiceOptions, ParsedDeclaration, PendingDocProjection, PendingSourceSnapshot, PendingsMarkdownEnv, RefreshOptions, type Result, type ResultErr, type ResultOk, RuntimeEnv, RuntimeEnvChannel, RuntimeEnvError, RuntimeEnvResolution, RuntimeEnvResult, SourceFieldValue, SourceViolation, VerifyError, VerifyReport, WriteMonthOptions, failure, loadPendingSource, monthRelDir, normalizeFrontmatterQuotes, parseDeclaration, pendingDocFileName, pendingsMarkdownEnvKit, renderAlignedTable, renderCatalog, renderDataRootReadme, renderMonthReadme, renderPendingDocument, resolveEnv, resolveRuntimeEnv, runConvert, runVerify, success };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import"./rolldown-runtime-BqT_7tdF.js";import{contentHash as e,createCatalogReconciler as t,createCatalogService as n,createEnvKit as r,createPartitionWriter as i,pipelineFrontmatter as a,splitDocument as o,stringifyFrontmatter as s}from"@longzai-intelligence-markdown/data-engine";import{existsSync as c,readFileSync as l,readdirSync as u}from"node:fs";import{join as d,resolve as f}from"node:path";import{loadPendingsMarkdownConfig as p}from"@longzai-intelligence-pendings-markdown/config";const m=/(:\s|\s-\s)"((?:[^"\\]|\\.)*)"/g,h=e=>`'${e.replaceAll(`'`,`''`)}'`,ee=e=>`"${e.replaceAll(/(["\\])/g,`\\$1`)}"`;function g(e){return e.replace(m,(e,t,n)=>{let r=n.replaceAll(`\\"`,`"`).replaceAll(`\\\\`,`\\`);return(r.match(/["\\]/g)??[]).length<(r.match(/'/g)??[]).length?`${t}${ee(r)}`:`${t}${h(r)}`})}function _(e){let t=0;for(let n of e)t+=n.charCodeAt(0)>255?2:1;return t}function v(e,t){return`${e}${` `.repeat(Math.max(0,t-_(e)))}`}function y(e,t){let n=e.map((e,n)=>{let r=[e,...t.map(e=>e[n]??``)];return Math.max(...r.map(_))});return[`| ${e.map((e,t)=>v(e,n[t]??0)).join(` | `)} |`,`| ${n.map(e=>`-`.repeat(e)).join(` | `)} |`,...t.map(e=>`| ${e.map((e,t)=>v(e??``,n[t]??0)).join(` | `)} |`)]}function b(e){return`${e}.pending.md`}function x(t,n){let r=`${t.body.replace(/\n+$/,``)}\n`,i=e(r),o=a({kind:`pending-doc`,feedPipelineId:`pendings-markdown`,plugin:`pendings`,sourceId:`pendings-data-home`,generatedAt:n,hash:i,extra:{...t.fields}});return{content:`${g(s(o))}\n${r}`,hash:i}}function S(e){let t=0,n=0,r=0;for(let i of e){let e=i.fields.status;e===`decided`?n+=1:e===`dropped`?r+=1:t+=1}return{pending:t,decided:n,dropped:r}}function C(t,n,r){let i=S(n),o=[];o.push(`# ${t} 待裁档投影`,``),o.push(`共 ${n.length} 篇,待裁 ${i.pending},已裁决 ${i.decided},废弃 ${i.dropped}。`,``),o.push(...y([`待裁项`,`类别`,`优先级`,`状态`,`标题`],n.map(e=>[`[${e.slug}](${b(e.slug)})`,`${e.fields.kind}`,`${e.fields.priority}`,`${e.fields.status}`,`${e.fields.title}`]))),o.push(``);let c=o.join(`
|
|
2
|
+
`),l=e(c),u=a({kind:`readme`,feedPipelineId:`pendings-markdown`,plugin:`pendings`,sourceId:`pendings-data-home`,generatedAt:r,hash:l,extra:{month:t,doc_count:n.length,pending_count:i.pending,decided_count:i.decided,dropped_count:i.dropped}});return{content:`${g(s(u))}\n${c}`,hash:l}}function w(e){return`pendings/${e}`}function T(t,n){let r=t.reduce((e,t)=>e+t.docCount,0),i=[];i.push(`# pendings 全局投影目录册`,``),i.push(`共 ${t.length} 个月目录 / ${r} 篇待裁档投影。`,``),i.push(...y([`月份`,`档数`,`目录`],t.map(e=>[`[${e.month}](${w(e.month)}/)`,`${e.docCount}`,`${w(e.month)}/`]))),i.push(``);let o=i.join(`
|
|
3
|
+
`),c=e(o),l=a({kind:`catalog`,feedPipelineId:`pendings-markdown`,plugin:`pendings`,sourceId:`pendings-data-home`,generatedAt:n,hash:c,extra:{month_count:t.length,doc_total:r}});return{content:`${g(s(l))}\n${o}`,hash:c}}function E(){return"# longzai-intelligence-pendings-data\n\npendings 待裁档 markdown 全局投影数据区:由 `lzi-pendings-markdown` 即 longzai-intelligence-pendings-markdown 仓从源台账 data-home 确定性转换生成并托管。\n\n## 组织规则\n\n- 分区键:待裁档 `raised` 提出日期的年月段即 `YYYY-MM`。\n- 数据根整体为单一 git 仓:唯一数据父目录 `pendings/` 之下按年月一层分层,月目录为普通被跟踪目录非嵌套仓。\n- 月目录内 `README.md` 即当月概览与索引表,与投影档 `<slug>.pending.md` 一档一文件平铺。\n- 跨目录检索与统计走根 `catalog.md`,单个月目录自包含可独立消费。\n- 台账写路径唯一在源 data-home 即 `lzi-pendings` 九命令,本仓只读投影不回写。\n\n## 存储纪律\n\n- 元数据一律随 markdown frontmatter,仓内禁任何 JSON 元数据文件。\n- 幂等:`content_hash` 即正文规范化 SHA-256 相同跳过不同覆盖,历史靠 git,重跑 `convert` 零变更时零写入。\n- 保留字:月目录内 `README.md` 与投影档,数据根内 `README.md` 与 `catalog.md` 与 `pendings/`。\n"}const D=/^\d{4}-\d{2}$/;function O(e){return u(e).filter(e=>e.endsWith(`.pending.md`)&&!e.startsWith(`.`))}function k(e){let t=d(e,`pendings`);if(!c(t))return[];let n=[],r=[...u(t,{withFileTypes:!0})].sort((e,t)=>e.name<t.name?-1:1);for(let e of r){if(!e.isDirectory()||!D.test(e.name))continue;let r=O(d(t,e.name));r.length!==0&&n.push({month:e.name,docCount:r.length})}return n}function A(e){return n({dataRoot:e.dataRoot,rootFiles:[{path:`.gitignore`,content:`# 机器本地配置(.env 本地实值;配置文件机器无关入库跟踪,不忽略)
|
|
4
|
+
.env
|
|
5
|
+
|
|
6
|
+
# macOS
|
|
7
|
+
.DS_Store
|
|
8
|
+
`},{path:`README.md`,content:E()}],initRootRepoAtEnsure:!0,scan:async()=>k(e.dataRoot),renderCatalog:T,reconcile:t({countFields:[{headKey:`month_count`,actual:e=>e.length},{headKey:`doc_total`,actual:e=>e.reduce((e,t)=>e+t.docCount,0)}],rowPattern:/\| +\[(\d{4}-\d{2})\]\([^)]*\) +\|/g,keyOfEntry:e=>e.month,keyNoun:`月目录`}),commit:{defaultEnabled:!1,message:()=>`pendings 投影目录册更新`}})}var j=class{dataRoot;service;constructor(e){this.dataRoot=e.dataRoot,this.service=A(e)}async scan(){return this.service.scan()}async ensureRoot(e){return this.service.ensureRoot(e)}async refresh(e={}){return this.service.refresh(e)}async check(){return this.service.check()}};const M=/^\d{4}-\d{2}$/;var N=class{dataRoot;writer;constructor(e){this.dataRoot=e.dataRoot,this.writer=i({dataRoot:this.dataRoot,partitionDir:e=>d(this.dataRoot,`pendings`,e),entryRelPath:(e,t)=>`pendings/${e}/${b(t.slug)}`,renderEntry:x,sortEntries:e=>[...e].sort((e,t)=>e.slug<t.slug?-1:1),renderPartitionReadme:C,validatePartition:e=>{if(!M.test(e))throw Error(`年月格式非法:${e},应为 YYYY-MM`)},validateEntry:(e,t)=>{if(t.month!==e)throw Error(`条目年月 ${t.month} 与目标分区 ${e} 不一致`)}})}async writeMonth(e,t,n={}){return await this.writer.writePartition(e,t,{dryRun:n.dryRun===!0,commit:!1})}};const P=e=>e.length>=2&&e.startsWith(`"`)&&e.endsWith(`"`)?e.slice(1,-1):e,F=e=>{let t={},n={};if(!e.startsWith(`---
|
|
9
|
+
`))return{head:t,arrays:n,body:e};let r=e.indexOf(`
|
|
10
|
+
---
|
|
11
|
+
`,4);if(r===-1)return{head:t,arrays:n,body:e};let i=e.slice(4,r).split(`
|
|
12
|
+
`),a=e.slice(r+5).replace(/^\n/,``),o=null;for(let e of i){if(e.startsWith(` - `)&&o!==null){let t=P(e.slice(4).trim());n[o]=[...n[o]??[],t];continue}if(o=null,e.endsWith(`: []`)){o=e.slice(0,-4),n[o]=[];continue}if(e.endsWith(`:`)){o=e.slice(0,-1),n[o]=[];continue}let r=e.indexOf(`: `);r>0&&!e.startsWith(` `)&&(t[e.slice(0,r)]=P(e.slice(r+2)))}return{head:t,arrays:n,body:a}},I=`pendings`,L=/^\d{4}-\d{2}$/,R=/^\d{4}-\d{2}-\d{2}$/,te=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,ne=[`choice`,`approve`,`inform`],z=[`P0`,`P1`,`P2`,`P3`],B=[`pending`,`decided`,`dropped`],V={id:e=>te.test(e)?null:`id 非 kebab 形态:${e}`,title:e=>e.length>=1?null:`title 为空`,kind:e=>ne.includes(e)?null:`kind 非法:${e}`,priority:e=>z.includes(e)?null:`priority 非法:${e}`,status:e=>B.includes(e)?null:`status 非法:${e}`,raised:e=>R.test(e)?null:`raised 非 YYYY-MM-DD:${e}`},H={due:e=>R.test(e)?null:`due 非 YYYY-MM-DD:${e}`,origin_repo:e=>/^longzai-intelligence-[a-z0-9-]+$/.test(e)?null:`origin_repo 形态非法:${e}`,origin:e=>e.length>=1?null:`origin 为空`,recommendation:e=>e.length>=1?null:`recommendation 为空`,decision:e=>e.length>=1?null:`decision 为空`,decided_by:e=>e.length>=1?null:`decided_by 为空`,decided_at:e=>R.test(e)?null:`decided_at 非 YYYY-MM-DD:${e}`,decision_basis:e=>e.length>=1?null:`decision_basis 为空`},U=[`options`,`context_refs`];function W(e,t){let n=[],r=/* @__PURE__ */ new Set([...Object.keys(V),...Object.keys(H),...U]);for(let[t,r]of Object.entries(V)){let i=e[t];if(typeof i!=`string`){n.push(`必填字段缺失或非标量:${t}`);continue}let a=r(i);a!==null&&n.push(a)}for(let[t,r]of Object.entries(H)){let i=e[t];if(i===void 0)continue;if(typeof i!=`string`){n.push(`可选字段非标量:${t}`);continue}let a=r(i);a!==null&&n.push(a)}for(let t of U){let r=e[t];if(r!==void 0){if(!Array.isArray(r))n.push(`数组字段非数组形态:${t}`);else for(let e of r)if(e.length<1){n.push(`数组字段含空项:${t}`);break}}}for(let t of Object.keys(e))r.has(t)||n.push(`未知字段:${t}`);let i=e.id;return typeof i==`string`&&i!==t&&n.push(`id 字段 ${i} 与文件名主干 ${t} 不一致`),n}function G(e){let t=d(e,I),n=[],r=[];if(!c(t))return{docs:n,violations:r};let i=[...u(t,{withFileTypes:!0})].sort((e,t)=>e.name<t.name?-1:1);for(let a of i){if(!a.isDirectory()||!L.test(a.name))continue;let i=u(d(t,a.name)).sort();for(let t of i){if(!t.endsWith(`.pending.md`))continue;let i=`${I}/${a.name}/${t}`,o=l(d(e,i),`utf8`),s=F(o),c={...s.head,...s.arrays},u=t.slice(0,-11),f=W(c,u);f.length>0?r.push({relativePath:i,violations:f}):n.push({slug:u,month:a.name,fields:c,body:s.body})}}return{docs:n.sort((e,t)=>`${e.month}-${e.slug}`<`${t.month}-${t.slug}`?-1:1),violations:r}}function K(e){return{ok:!0,value:e}}function q(e){return{ok:!1,error:e}}const J=/^\d{4}-\d{2}$/;function Y(e){let t=e.month!==void 0,n=[t,e.all===!0].filter(Boolean).length;if(n===0)return q({code:`SELECTION_INVALID`,message:`缺少选择器:--month <YYYY-MM> 与 --all 二选一`});if(n>1)return q({code:`SELECTION_INVALID`,message:`选择器互斥:--month 与 --all 只能选一种`});if(t){let t=e.month;return t===void 0||!J.test(t)?q({code:`MONTH_INVALID`,message:`--month 格式非法:${t??`空`},应为 YYYY-MM`}):K([t])}return K(null)}async function X(e,t){let n=Y(t);if(!n.ok)return q(n.error);let r=G(e.sourceHome),i=n.value===null?[...new Set(r.docs.map(e=>e.month))].sort():n.value.filter(e=>r.docs.some(t=>t.month===e)),a=new N({dataRoot:e.dataRoot}),o={dryRun:t.dryRun===!0},s=[];for(let e of i){let t=r.docs.filter(t=>t.month===e),n=await a.writeMonth(e,t,o);s.push({month:e,docs:t.length,written:n.written,skipped:n.skipped})}let c=await new j({dataRoot:e.dataRoot}).refresh(o);return K({months:s,violations:r.violations,catalog:c})}const Z=`LZI_PENDINGS_DATA_HOME`,Q=r({variables:[{name:Z,comment:`源台账 data-home 即 pendings 仓待裁档与目录册所在数据区,本工具只读消费`,placeholder:`/path/to/pendings-data-home`}],toEnvConfig:e=>({sourceHome:f(e.LZI_PENDINGS_DATA_HOME??``)}),defaultTemplateTitle:`lzi-pendings-markdown 环境配置`});function $(e=process.env){return Q.resolveEnv(e)}const re=Q;async function ie(e){let t=await p(e);if(!t.ok)return{ok:!1,error:t.error};let n=$();return n.ok?{ok:!0,value:{channel:`config-file`,env:{dataRoot:t.config.dataRoot,sourceHome:n.value.sourceHome},configPath:t.path}}:{ok:!1,error:n.error}}async function ae(t){if(!c(t.dataRoot))return q({code:`DATA_ROOT_MISSING`,message:`数据根不存在:${t.dataRoot}`});let n=new j({dataRoot:t.dataRoot}),r=await n.scan(),i=[],a=[],s=/* @__PURE__ */ new Map;for(let n of r){let r=d(t.dataRoot,`pendings`,n.month),f=c(r)?u(r).filter(e=>e.endsWith(`.pending.md`)&&!e.startsWith(`.`)):[];for(let t of f){let c=d(r,t),{head:u,body:f}=o(l(c,`utf8`)),p=e(f);u.content_hash!==void 0&&u.content_hash!==p&&i.push({file:c,expected:u.content_hash,actual:p});let m=t.slice(0,-11),h=s.get(m);h===void 0?s.set(m,n.month):a.push(`slug ${m} 跨月重复:${h} 与 ${n.month}`)}let p=d(r,`README.md`);if(c(p)){let{head:e}=o(l(p,`utf8`));e.doc_count!==void 0&&e.doc_count!==String(f.length)&&a.push(`${n.month}/README.md 登记档数 ${e.doc_count} 与实测 ${f.length} 不符`)}else a.push(`${n.month} 缺 README.md`)}let f=await n.check();return a.push(...f),K({hashDrifts:i,issues:a,ok:i.length===0&&a.length===0})}export{j as CatalogService,Z as ENV_SOURCE_HOME,N as MonthRepoService,q as failure,G as loadPendingSource,w as monthRelDir,g as normalizeFrontmatterQuotes,F as parseDeclaration,b as pendingDocFileName,re as pendingsMarkdownEnvKit,y as renderAlignedTable,T as renderCatalog,E as renderDataRootReadme,C as renderMonthReadme,x as renderPendingDocument,$ as resolveEnv,ie as resolveRuntimeEnv,X as runConvert,ae as runVerify,K as success};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"node:module";export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-pendings-markdown/core",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Longzai Intelligence pendings markdown core - 投影转换引擎,源台账读取与确定性渲染与幂等写入",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"convert",
|
|
7
|
+
"core",
|
|
8
|
+
"longzai-intelligence",
|
|
9
|
+
"pendings-markdown",
|
|
10
|
+
"render"
|
|
11
|
+
],
|
|
12
|
+
"license": "UNLICENSED",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "lzi-builder",
|
|
27
|
+
"build:prod": "NODE_ENV=production lzi-builder",
|
|
28
|
+
"prepublishOnly": "bun run build:prod",
|
|
29
|
+
"typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
|
|
30
|
+
"typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
|
|
31
|
+
"typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
|
|
32
|
+
"typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
|
|
33
|
+
"lint": "oxlint && oxfmt --check",
|
|
34
|
+
"lint:fix": "oxlint --fix && oxfmt",
|
|
35
|
+
"test": "lzi-bun test",
|
|
36
|
+
"test:watch": "lzi-bun test --watch",
|
|
37
|
+
"test:coverage": "lzi-bun test --coverage",
|
|
38
|
+
"clean": "lzi-dev-tools clean"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@longzai-intelligence-markdown/data-engine": "^0.0.6",
|
|
42
|
+
"@longzai-intelligence-pendings-markdown/config": "0.0.1",
|
|
43
|
+
"zod": "^4.6.5"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/bun": "^1.4.4"
|
|
47
|
+
}
|
|
48
|
+
}
|