cardbuddy 0.12.0 → 0.12.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.
|
@@ -272,13 +272,14 @@ const CARD_PATCH_TOOL = {
|
|
|
272
272
|
type: 'function',
|
|
273
273
|
function: {
|
|
274
274
|
name: 'card_patch',
|
|
275
|
-
description: '按 JSON 点路径(数组用数字段)对卡片 schema/data 做最小修改并写回;大卡必用本工具,禁止用 card_write 整包重写。路径必须先用 card_grep 拿真实路径——schema 的节点树是 view.components[].slots[].components[](不是 view.children)。路径中段不存在会直接报错(不再静默新建分支),确要新建传 create:true
|
|
275
|
+
description: '按 JSON 点路径(数组用数字段)对卡片 schema/data 做最小修改并写回;大卡必用本工具,禁止用 card_write 整包重写。路径必须先用 card_grep 拿真实路径——schema 的节点树是 view.components[].slots[].components[](不是 view.children)。路径中段不存在会直接报错(不再静默新建分支),确要新建传 create:true。patches(改/增)与 deletes(删)至少给一个,可只删不改(清理无用样式项、多余节点)。仓库根下走 card_write 管线(带历史快照与校验)。',
|
|
276
276
|
parameters: {
|
|
277
277
|
type: 'object',
|
|
278
278
|
properties: {
|
|
279
279
|
id: { type: 'string', description: '卡片 id' },
|
|
280
280
|
patches: {
|
|
281
281
|
type: 'array',
|
|
282
|
+
description: '要写入的 {path,value} 列表;只删除时可省略(此时必须给 deletes)',
|
|
282
283
|
items: {
|
|
283
284
|
type: 'object',
|
|
284
285
|
properties: {
|
|
@@ -288,11 +289,11 @@ const CARD_PATCH_TOOL = {
|
|
|
288
289
|
required: ['path', 'value'],
|
|
289
290
|
},
|
|
290
291
|
},
|
|
291
|
-
deletes: { type: 'array', items: { type: 'string' }, description: '要删除的 JSON
|
|
292
|
+
deletes: { type: 'array', items: { type: 'string' }, description: '要删除的 JSON 点路径;可单独使用(只删不改)' },
|
|
292
293
|
target: { type: 'string', enum: ['schema', 'data'], description: '默认 schema' },
|
|
293
294
|
create: { type: 'boolean', description: '路径中段不存在时是否新建分支(默认 false = 响亮报错)' },
|
|
294
295
|
},
|
|
295
|
-
required: ['id'
|
|
296
|
+
required: ['id'],
|
|
296
297
|
},
|
|
297
298
|
},
|
|
298
299
|
}
|
|
@@ -352,12 +353,38 @@ function applyByPath(doc, p, setter, { create = false } = {}) {
|
|
|
352
353
|
|
|
353
354
|
async function cardPatch(root, args, dispatch, { allowDispatch = false } = {}) {
|
|
354
355
|
const { id, patches = [], deletes = [], target = 'schema' } = args || {}
|
|
355
|
-
if (!Array.isArray(patches)
|
|
356
|
+
if (!Array.isArray(patches)) throw new Error('patches 必须是数组')
|
|
357
|
+
if (!Array.isArray(deletes)) throw new Error('deletes 必须是数组')
|
|
358
|
+
// 「只删不改」是合法操作(清理无用样式项 / 多余节点);真正的错误是两个都空 —— 空补丁什么都不做,
|
|
359
|
+
// 却会照样走一遍 card_write 管线、平白多存一份历史快照,所以在这里响亮拒掉。
|
|
360
|
+
if (!patches.length && !deletes.length) throw new Error('patches 与 deletes 至少给一个(空补丁无意义)')
|
|
356
361
|
const file = path.join(root, 'src', 'cards', String(id || ''), target === 'data' ? 'data.json' : 'schema.json')
|
|
357
362
|
const doc = JSON.parse(fs.readFileSync(file, 'utf8'))
|
|
358
363
|
const create = args.create === true
|
|
359
364
|
for (const pt of patches) applyByPath(doc, pt.path, (obj, k) => (obj[k] = pt.value), { create })
|
|
360
|
-
|
|
365
|
+
// 删数组元素必须 splice:早先用 delete obj[k],在数组上只留一个 null 空洞
|
|
366
|
+
// (properties 变成 [null, {...}]),补丁报「成功」却把 schema 写成稀疏数组,渲染与校验随后就崩。
|
|
367
|
+
// 同一父数组里删多项时按原始下标从大到小删 —— splice 会让后面的索引左移,升序删会误删邻居。
|
|
368
|
+
const orderedDeletes = [...deletes].sort((a, b) => {
|
|
369
|
+
const sa = String(a).split('.')
|
|
370
|
+
const sb = String(b).split('.')
|
|
371
|
+
const pa = sa.slice(0, -1).join('.')
|
|
372
|
+
const pb = sb.slice(0, -1).join('.')
|
|
373
|
+
if (pa !== pb) return pa < pb ? -1 : 1
|
|
374
|
+
const na = Number(sa[sa.length - 1])
|
|
375
|
+
const nb = Number(sb[sb.length - 1])
|
|
376
|
+
return Number.isFinite(na) && Number.isFinite(nb) ? nb - na : 0
|
|
377
|
+
})
|
|
378
|
+
for (const d of orderedDeletes)
|
|
379
|
+
applyByPath(
|
|
380
|
+
doc,
|
|
381
|
+
d,
|
|
382
|
+
(obj, k) => {
|
|
383
|
+
if (Array.isArray(obj)) obj.splice(Number(k), 1)
|
|
384
|
+
else delete obj[k]
|
|
385
|
+
},
|
|
386
|
+
{ create },
|
|
387
|
+
)
|
|
361
388
|
// 工程根:走 card_write 管线(历史快照 + validate/render_status);其它根(测试/自定义)直接落盘。
|
|
362
389
|
// 仓库内运行由「root === 仓库根」判定;cardbuddy 发布态快照根在包内、永不等于工程根,
|
|
363
390
|
// 故由宿主显式 allowDispatch 开启(它已把 CARD_ROOT 指到同一个工程根,dispatch 落点一致)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cardbuddy",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Local dev service for the CardBuddy card editor — decouples card CRUD (sync/save/validate/render-status/screenshot) from the static public editor, so the editor can be deployed to any static host while each developer runs a local service against their own card source.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|