@bettercms-ai/convert 0.15.0 → 0.16.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/CHANGELOG.md +6 -0
- package/dist/cli.js +54 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -990,7 +990,11 @@ declare const FORM_SCRIPT = "<script>\nfunction bcmsPhone(cc,raw,trunk){var d=St
|
|
|
990
990
|
* `ConversionReceipt` with an empty path arithmetic and the lane's own account under `forms`, so
|
|
991
991
|
* `submit_conversion_receipt` takes it unchanged — the server's invariant reads `paths` only.
|
|
992
992
|
*/
|
|
993
|
-
|
|
993
|
+
interface WireFormsOptions {
|
|
994
|
+
/** Form id or name → the file its `<form>` is in. The operator's answer to FORM_AMBIGUOUS. */
|
|
995
|
+
pins?: Record<string, string>;
|
|
996
|
+
}
|
|
997
|
+
declare function wireForms(briefIn: Brief, sources: SourceFile[], options_?: WireFormsOptions): Promise<{
|
|
994
998
|
files: PlanFile[];
|
|
995
999
|
receipt: ConversionReceipt;
|
|
996
1000
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -6493,7 +6493,7 @@ function wire(source, candidate, form) {
|
|
|
6493
6493
|
source.appendLeft(el.inner.end - tail.length, `${tail || "\n"}${messageFor(dialect)}`);
|
|
6494
6494
|
}
|
|
6495
6495
|
}
|
|
6496
|
-
async function wireForms(briefIn, sources) {
|
|
6496
|
+
async function wireForms(briefIn, sources, options_ = {}) {
|
|
6497
6497
|
const brief = readBrief(briefIn);
|
|
6498
6498
|
const forms = brief.forms ?? [];
|
|
6499
6499
|
const candidates = [];
|
|
@@ -6531,7 +6531,33 @@ async function wireForms(briefIn, sources) {
|
|
|
6531
6531
|
}
|
|
6532
6532
|
const holds = (c, f) => f.fields.filter((field) => c.controls.has(field.key)).length;
|
|
6533
6533
|
const covers2 = (c, f) => f.fields.length > 0 && holds(c, f) === f.fields.length;
|
|
6534
|
+
const posts = (c) => new Set(c.controls.values()).size;
|
|
6535
|
+
const samePath = (a, b) => a.replace(/\\/g, "/").replace(/^\.\//, "") === b.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
6534
6536
|
const options = new Map(forms.map((f) => [f.id, candidates.filter((c) => covers2(c, f))]));
|
|
6537
|
+
const pinned = /* @__PURE__ */ new Map();
|
|
6538
|
+
for (const [ref, file] of Object.entries(options_.pins ?? {})) {
|
|
6539
|
+
const form = forms.find((f) => f.id === ref || f.name === ref);
|
|
6540
|
+
if (!form) throw new Error(`--pin ${ref}: the brief lists no form with that id or name.`);
|
|
6541
|
+
pinned.set(form.id, file);
|
|
6542
|
+
options.set(form.id, options.get(form.id).filter((c) => samePath(c.file, file)));
|
|
6543
|
+
for (const other of forms) {
|
|
6544
|
+
if (other.id !== form.id) options.set(other.id, options.get(other.id).filter((c) => !samePath(c.file, file)));
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
for (const c of candidates) {
|
|
6548
|
+
const claimants = forms.filter((f) => options.get(f.id).includes(c));
|
|
6549
|
+
if (claimants.length < 2) continue;
|
|
6550
|
+
const top = Math.max(...claimants.map((f) => holds(c, f)));
|
|
6551
|
+
const winners = claimants.filter((f) => holds(c, f) === top);
|
|
6552
|
+
if (winners.length !== 1) continue;
|
|
6553
|
+
for (const f of claimants) if (f !== winners[0]) options.set(f.id, options.get(f.id).filter((x) => x !== c));
|
|
6554
|
+
}
|
|
6555
|
+
for (const f of forms) {
|
|
6556
|
+
const list = options.get(f.id);
|
|
6557
|
+
if (list.length < 2) continue;
|
|
6558
|
+
const exact = list.filter((c) => posts(c) === f.fields.length);
|
|
6559
|
+
if (exact.length === 1) options.set(f.id, exact);
|
|
6560
|
+
}
|
|
6535
6561
|
const wanted = /* @__PURE__ */ new Map();
|
|
6536
6562
|
for (const list of options.values()) for (const c of list) wanted.set(c, (wanted.get(c) ?? 0) + 1);
|
|
6537
6563
|
const matched = [];
|
|
@@ -6542,7 +6568,12 @@ async function wireForms(briefIn, sources) {
|
|
|
6542
6568
|
for (const form of forms) {
|
|
6543
6569
|
const list = options.get(form.id) ?? [];
|
|
6544
6570
|
if (list.length > 1) {
|
|
6545
|
-
pend2(
|
|
6571
|
+
pend2(
|
|
6572
|
+
form,
|
|
6573
|
+
"FORM_AMBIGUOUS",
|
|
6574
|
+
void 0,
|
|
6575
|
+
`${list.length} forms post every field of "${form.name}": ${list.map((c) => c.file).join(", ")}. Name the right one with --pin "${form.name}=<file>".`
|
|
6576
|
+
);
|
|
6546
6577
|
continue;
|
|
6547
6578
|
}
|
|
6548
6579
|
if (list.length === 1 && (wanted.get(list[0]) ?? 0) > 1) {
|
|
@@ -6551,7 +6582,13 @@ async function wireForms(briefIn, sources) {
|
|
|
6551
6582
|
}
|
|
6552
6583
|
if (list.length === 0) {
|
|
6553
6584
|
const [best] = candidates.map((c) => ({ c, n: holds(c, form) })).filter((x) => x.n > 0).sort((a, b) => b.n - a.n);
|
|
6554
|
-
|
|
6585
|
+
const pin = pinned.get(form.id);
|
|
6586
|
+
if (pin) {
|
|
6587
|
+
pend2(form, "FORM_NOT_IN_SOURCE", pin, `the pinned file has no <form> posting ${form.fields.map((f) => f.key).join(", ")}.`);
|
|
6588
|
+
} else if (best && best.n === form.fields.length) {
|
|
6589
|
+
const owner = forms.find((f) => f !== form && options.get(f.id).includes(best.c));
|
|
6590
|
+
pend2(form, "FORM_NOT_IN_SOURCE", best.c.file, `the only <form> posting ${form.fields.map((f) => f.key).join(", ")} is "${owner?.name ?? "another form"}"'s.`);
|
|
6591
|
+
} else if (best) {
|
|
6555
6592
|
const missing = form.fields.filter((f) => !best.c.controls.has(f.key)).map((f) => f.key);
|
|
6556
6593
|
pend2(form, "FIELD_UNMATCHED", best.c.file, `no control posts ${missing.join(", ")} in the <form> that posts its other fields.`);
|
|
6557
6594
|
} else if (unreadable[0]) {
|