@wildwinter/toolkit 0.2.0 → 0.2.2
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 +20 -0
- package/conformance/extensions/manifest.json +1023 -158
- package/conformance/extensions/merge.json +46 -1
- package/conformance/extensions/values.json +736 -91
- package/dist/extensions.cjs +88 -3
- package/dist/extensions.cjs.map +1 -1
- package/dist/extensions.d.cts +36 -1
- package/dist/extensions.d.ts +36 -1
- package/dist/extensions.js +86 -4
- package/dist/extensions.js.map +1 -1
- package/extensions.md +10 -2
- package/package.json +1 -1
package/dist/extensions.cjs
CHANGED
|
@@ -406,7 +406,7 @@ function targetProblems(host, kind, target, path, settings, out) {
|
|
|
406
406
|
if (!SCALAR_TYPES.includes(claim.type)) {
|
|
407
407
|
out.push(err2("claim-type", atKey(at, "type"), "a claim presents a host field, which is a scalar"));
|
|
408
408
|
} else {
|
|
409
|
-
typeProblems(host, claim, at, false, out);
|
|
409
|
+
typeProblems(host, claim, at, false, out, true);
|
|
410
410
|
}
|
|
411
411
|
if (typeof claim.setting !== "string" || !settings.has(claim.setting)) {
|
|
412
412
|
out.push(err2("claim-setting", atKey(at, "setting"), `a claim names its field through a setting, and "${String(claim.setting)}" is not one of the manifest's settings`));
|
|
@@ -449,7 +449,7 @@ function fieldListProblems(host, fields, path, topLevel, out) {
|
|
|
449
449
|
}
|
|
450
450
|
});
|
|
451
451
|
}
|
|
452
|
-
function typeProblems(host, decl, path, named, out) {
|
|
452
|
+
function typeProblems(host, decl, path, named, out, claim = false) {
|
|
453
453
|
const typeAt = atKey(path, "type");
|
|
454
454
|
if (decl.type === "string") {
|
|
455
455
|
out.push(err2("string-type", typeAt, 'the text type is spelled "text"'));
|
|
@@ -465,6 +465,7 @@ function typeProblems(host, decl, path, named, out) {
|
|
|
465
465
|
case "enum":
|
|
466
466
|
case "flags": {
|
|
467
467
|
const values = decl.values;
|
|
468
|
+
if (claim && values === void 0) break;
|
|
468
469
|
if (!Array.isArray(values) || values.length === 0) {
|
|
469
470
|
out.push(err2("values-empty", at("values"), `an ${decl.type === "enum" ? "enum" : "flags field"} lists its values`));
|
|
470
471
|
sound = false;
|
|
@@ -483,6 +484,7 @@ function typeProblems(host, decl, path, named, out) {
|
|
|
483
484
|
break;
|
|
484
485
|
}
|
|
485
486
|
case "quality": {
|
|
487
|
+
if (claim && decl.stages === void 0) break;
|
|
486
488
|
for (const p of expr.qualityDeclarationProblems(decl.stages)) {
|
|
487
489
|
out.push(err2(
|
|
488
490
|
`quality-${p.kind === "default-not-a-stage" ? "default" : p.kind}`,
|
|
@@ -542,7 +544,11 @@ function typeProblems(host, decl, path, named, out) {
|
|
|
542
544
|
}
|
|
543
545
|
}
|
|
544
546
|
if (decl.renamedStages !== void 0) renamedStagesProblems(decl, at("renamedStages"), out);
|
|
545
|
-
if (decl.valueHelp !== void 0) {
|
|
547
|
+
if (decl.valueHelp !== void 0 && claim) {
|
|
548
|
+
if (!isObject(decl.valueHelp) || !["enum", "flags", "quality"].includes(decl.type)) {
|
|
549
|
+
out.push(err2("value-help", at("valueHelp"), "value help describes the values of an enum or flags field, or a quality's stages"));
|
|
550
|
+
}
|
|
551
|
+
} else if (decl.valueHelp !== void 0) {
|
|
546
552
|
const vocabulary = decl.type === "quality" ? decl.stages : decl.type === "enum" || decl.type === "flags" ? decl.values : void 0;
|
|
547
553
|
if (vocabulary === void 0 || !isObject(decl.valueHelp)) {
|
|
548
554
|
out.push(err2("value-help", at("valueHelp"), "value help describes the values of an enum or flags field, or a quality's stages"));
|
|
@@ -623,10 +629,19 @@ function targetOf(manifest, host, kind) {
|
|
|
623
629
|
const kinds = manifest?.targets[host];
|
|
624
630
|
return kinds !== void 0 && own(kinds, kind) ? kinds[kind] : void 0;
|
|
625
631
|
}
|
|
632
|
+
function effectiveClaim(claim, hostDecl) {
|
|
633
|
+
return {
|
|
634
|
+
...claim,
|
|
635
|
+
...claim.values === void 0 && hostDecl.values !== void 0 ? { values: hostDecl.values } : {},
|
|
636
|
+
...claim.stages === void 0 && hostDecl.stages !== void 0 ? { stages: hostDecl.stages } : {},
|
|
637
|
+
...claim.default === void 0 && hostDecl.default !== void 0 ? { default: hostDecl.default } : {}
|
|
638
|
+
};
|
|
639
|
+
}
|
|
626
640
|
|
|
627
641
|
// src/extensions/merge.ts
|
|
628
642
|
var ATOMIC = { kind: "atomic" };
|
|
629
643
|
var SET = { kind: "set" };
|
|
644
|
+
var COMMENTS = { kind: "comments" };
|
|
630
645
|
var mapOf = (of) => ({ kind: "map", of });
|
|
631
646
|
var keyedBy = (key, of, opts) => ({
|
|
632
647
|
kind: "keyed",
|
|
@@ -669,6 +684,7 @@ function hasShape(spec, v) {
|
|
|
669
684
|
return true;
|
|
670
685
|
case "set":
|
|
671
686
|
case "keyed":
|
|
687
|
+
case "comments":
|
|
672
688
|
return Array.isArray(v);
|
|
673
689
|
case "map":
|
|
674
690
|
case "object":
|
|
@@ -708,6 +724,8 @@ function mergeValue(spec, b, o, t, id, path, ctx) {
|
|
|
708
724
|
}
|
|
709
725
|
case "keyed":
|
|
710
726
|
return mergeKeyed(spec, asArr(b), o, t, path, ctx);
|
|
727
|
+
case "comments":
|
|
728
|
+
return mergeThreads(asArr(b), o, t, path, ctx);
|
|
711
729
|
}
|
|
712
730
|
}
|
|
713
731
|
function mergeKeyed(spec, B, O, T, path, ctx) {
|
|
@@ -786,6 +804,70 @@ function preservedOrder(B, O, T, survivors, path, ctx) {
|
|
|
786
804
|
for (const k of [...survivors.keys()].sort()) if (!result.includes(k)) result.push(k);
|
|
787
805
|
return result;
|
|
788
806
|
}
|
|
807
|
+
function mergeComments(base, ours, theirs, opts) {
|
|
808
|
+
return mergeTree(COMMENTS, base, ours, theirs, opts);
|
|
809
|
+
}
|
|
810
|
+
function mergeThreads(B, O, T, path, ctx) {
|
|
811
|
+
const index = (arr) => {
|
|
812
|
+
const m = /* @__PURE__ */ new Map();
|
|
813
|
+
for (const c of arr) if (isObject(c) && typeof c["id"] === "string") m.set(c["id"], c);
|
|
814
|
+
return m;
|
|
815
|
+
};
|
|
816
|
+
const Bm = index(B), Om = index(O), Tm = index(T);
|
|
817
|
+
const out = [];
|
|
818
|
+
for (const id of /* @__PURE__ */ new Set([...Bm.keys(), ...Om.keys(), ...Tm.keys()])) {
|
|
819
|
+
const b = Bm.get(id), o = Om.get(id), t = Tm.get(id);
|
|
820
|
+
const here = `${path}[${id}]`;
|
|
821
|
+
if (o === void 0 && t === void 0) continue;
|
|
822
|
+
if (![b, o, t].some((c) => Array.isArray(c?.["messages"]))) {
|
|
823
|
+
const v = o !== void 0 && t !== void 0 ? merge3(b, o, t, id, here, ctx) : b !== void 0 && ctx.eq(o ?? t, b) ? void 0 : o ?? t;
|
|
824
|
+
if (isObject(v)) out.push(v);
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
const messages = mergeMessages(b, o, t, id, here, ctx);
|
|
828
|
+
if (messages.length === 0 || messages.every((m) => m["deleted"] === true)) continue;
|
|
829
|
+
const fields = {};
|
|
830
|
+
if (o !== void 0 && t !== void 0) {
|
|
831
|
+
const B0 = b ?? {};
|
|
832
|
+
const flag = (c, k) => k === "resolved" ? c[k] === true ? true : void 0 : c[k];
|
|
833
|
+
for (const k of /* @__PURE__ */ new Set([...Object.keys(o), ...Object.keys(t), ...Object.keys(B0)])) {
|
|
834
|
+
if (k === "messages") continue;
|
|
835
|
+
const v = merge3(flag(B0, k), flag(o, k), flag(t, k), id, `${here}.${k}`, ctx);
|
|
836
|
+
if (v !== void 0) fields[k] = v;
|
|
837
|
+
}
|
|
838
|
+
} else {
|
|
839
|
+
for (const [k, v] of Object.entries(o ?? t)) if (k !== "messages") fields[k] = v;
|
|
840
|
+
}
|
|
841
|
+
out.push({ ...fields, messages });
|
|
842
|
+
}
|
|
843
|
+
const first = (c) => {
|
|
844
|
+
const m = asArr(c["messages"])[0];
|
|
845
|
+
return isObject(m) && typeof m["ts"] === "string" ? m["ts"] : "";
|
|
846
|
+
};
|
|
847
|
+
return out.sort((x, y) => first(x).localeCompare(first(y)) || String(x["id"]).localeCompare(String(y["id"])));
|
|
848
|
+
}
|
|
849
|
+
function mergeMessages(b, o, t, id, here, ctx) {
|
|
850
|
+
const keyOf = (m) => `${String(m["author"] ?? "")}|${String(m["ts"] ?? "")}`;
|
|
851
|
+
const index = (c) => {
|
|
852
|
+
const m = /* @__PURE__ */ new Map();
|
|
853
|
+
for (const x of asArr(c?.["messages"])) if (isObject(x)) m.set(keyOf(x), x);
|
|
854
|
+
return m;
|
|
855
|
+
};
|
|
856
|
+
const Bm = index(b), Om = index(o), Tm = index(t);
|
|
857
|
+
const out = [];
|
|
858
|
+
for (const k of /* @__PURE__ */ new Set([...Bm.keys(), ...Om.keys(), ...Tm.keys()])) {
|
|
859
|
+
const mb = Bm.get(k), mo = Om.get(k), mt = Tm.get(k);
|
|
860
|
+
if ([mb, mo, mt].some((m) => m?.["deleted"] === true) || mb !== void 0 && (mo === void 0 || mt === void 0)) {
|
|
861
|
+
out.push({ ...mo ?? mt ?? mb, body: "", deleted: true });
|
|
862
|
+
} else if (mo !== void 0 && mt !== void 0) {
|
|
863
|
+
out.push(merge3(mb, mo, mt, id, `${here}.messages[${k}]`, ctx));
|
|
864
|
+
} else {
|
|
865
|
+
out.push(mo ?? mt);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
const ts = (m) => String(m["ts"] ?? "");
|
|
869
|
+
return out.sort((x, y) => ts(x).localeCompare(ts(y)) || String(x["author"] ?? "").localeCompare(String(y["author"] ?? "")));
|
|
870
|
+
}
|
|
789
871
|
function strategyForType(decl) {
|
|
790
872
|
switch (decl.type) {
|
|
791
873
|
case "flags":
|
|
@@ -894,6 +976,7 @@ function orphanedEntries(data, exists) {
|
|
|
894
976
|
}
|
|
895
977
|
|
|
896
978
|
exports.ATOMIC = ATOMIC;
|
|
979
|
+
exports.COMMENTS = COMMENTS;
|
|
897
980
|
exports.HOSTS = HOSTS;
|
|
898
981
|
exports.MANIFEST_FILE_SUFFIX = MANIFEST_FILE_SUFFIX;
|
|
899
982
|
exports.MANIFEST_SCHEMA = MANIFEST_SCHEMA;
|
|
@@ -907,12 +990,14 @@ exports.claimClashes = claimClashes;
|
|
|
907
990
|
exports.compileEntry = compileEntry;
|
|
908
991
|
exports.compiledTarget = compiledTarget;
|
|
909
992
|
exports.defaultOf = defaultOf;
|
|
993
|
+
exports.effectiveClaim = effectiveClaim;
|
|
910
994
|
exports.entryProblems = entryProblems;
|
|
911
995
|
exports.extensionDataStrategy = extensionDataStrategy;
|
|
912
996
|
exports.keyedBy = keyedBy;
|
|
913
997
|
exports.manifestProblems = manifestProblems;
|
|
914
998
|
exports.mapOf = mapOf;
|
|
915
999
|
exports.markUnresolved = markUnresolved;
|
|
1000
|
+
exports.mergeComments = mergeComments;
|
|
916
1001
|
exports.mergeExtensionData = mergeExtensionData;
|
|
917
1002
|
exports.mergeTree = mergeTree;
|
|
918
1003
|
exports.objectOf = objectOf;
|