UNPKG

@bjoerge/mutiny

Version:

Tiny toolkit for working with Sanity mutations in JavaScript & TypeScript

517 lines (516 loc) 14.7 kB
import { parse } from "./_legacy/parse.esm.js"; import { stringify } from "./_legacy/stringify.esm.js"; import { decode as decode$1, decodeAll } from "./_legacy/decode.esm.js"; import { isObject } from "./_legacy/isObject.esm.js"; import { arrify } from "./_legacy/arrify.esm.js"; function decode(mutations) { return mutations.map(decodeMutation); } function decodeMutation(mutation) { const [type] = mutation; if (type === "delete") { const [, id] = mutation; return { id, type }; } else if (type === "create") { const [, document] = mutation; return { type, document }; } else if (type === "createIfNotExists") { const [, document] = mutation; return { type, document }; } else if (type === "createOrReplace") { const [, document] = mutation; return { type, document }; } else if (type === "patch") return decodePatchMutation(mutation); throw new Error(`Unrecognized mutation: ${JSON.stringify(mutation)}`); } function decodePatchMutation(mutation) { const [, type, id, serializedPath, , revisionId] = mutation, path = parse(serializedPath); if (type === "dec" || type === "inc") { const [, , , , [amount]] = mutation; return { type: "patch", id, patches: [{ path, op: { type: "inc", amount } }], ...createOpts(revisionId) }; } if (type === "unset") return { type: "patch", id, patches: [{ path, op: { type: "unset" } }], ...createOpts(revisionId) }; if (type === "insert") { const [, , , , [position, ref, items]] = mutation; return { type: "patch", id, patches: [ { path, op: { type: "insert", position, items, referenceItem: typeof ref == "string" ? { _key: ref } : ref } } ], ...createOpts(revisionId) }; } if (type === "set") { const [, , , , [value]] = mutation; return { type: "patch", id, patches: [{ path, op: { type: "set", value } }], ...createOpts(revisionId) }; } if (type === "setIfMissing") { const [, , , , [value]] = mutation; return { type: "patch", id, patches: [{ path, op: { type: "setIfMissing", value } }], ...createOpts(revisionId) }; } if (type === "diffMatchPatch") { const [, , , , [value]] = mutation; return { type: "patch", id, patches: [{ path, op: { type: "diffMatchPatch", value } }], ...createOpts(revisionId) }; } if (type === "truncate") { const [, , , , [startIndex, endIndex]] = mutation; return { type: "patch", id, patches: [{ path, op: { type: "truncate", startIndex, endIndex } }], ...createOpts(revisionId) }; } if (type === "assign") { const [, , , , [value]] = mutation; return { type: "patch", id, patches: [{ path, op: { type: "assign", value } }], ...createOpts(revisionId) }; } if (type === "replace") { const [, , , , [ref, items]] = mutation; return { type: "patch", id, patches: [ { path, op: { type: "replace", items, referenceItem: decodeItemRef(ref) } } ], ...createOpts(revisionId) }; } if (type === "upsert") { const [, , , , [position, referenceItem, items]] = mutation; return { type: "patch", id, patches: [ { path, op: { type: "upsert", items, referenceItem: decodeItemRef(referenceItem), position } } ], ...createOpts(revisionId) }; } throw new Error(`Invalid mutation type: ${type}`); } function decodeItemRef(ref) { return typeof ref == "string" ? { _key: ref } : ref; } function createOpts(revisionId) { return revisionId ? { options: { ifRevision: revisionId } } : null; } function encode$1(mutations) { return mutations.flatMap((m) => encodeMutation$2(m)); } function encodeItemRef$1(ref) { return typeof ref == "number" ? ref : ref._key; } function encodeMutation$2(mutation) { if (mutation.type === "create" || mutation.type === "createIfNotExists" || mutation.type === "createOrReplace") return [[mutation.type, mutation.document]]; if (mutation.type === "delete") return [["delete", mutation.id]]; if (mutation.type === "patch") return mutation.patches.map( (patch2) => { var _a; return maybeAddRevision( (_a = mutation.options) == null ? void 0 : _a.ifRevision, encodePatchMutation(mutation.id, patch2) ); } ); throw new Error(`Invalid mutation type: ${mutation.type}`); } function encodePatchMutation(id, patch2) { const { op } = patch2, path = stringify(patch2.path); if (op.type === "unset") return ["patch", "unset", id, path, []]; if (op.type === "diffMatchPatch") return ["patch", "diffMatchPatch", id, path, [op.value]]; if (op.type === "inc" || op.type === "dec") return ["patch", op.type, id, path, [op.amount]]; if (op.type === "set") return ["patch", op.type, id, path, [op.value]]; if (op.type === "setIfMissing") return ["patch", op.type, id, path, [op.value]]; if (op.type === "insert") return [ "patch", "insert", id, path, [op.position, encodeItemRef$1(op.referenceItem), op.items] ]; if (op.type === "upsert") return [ "patch", "upsert", id, path, [op.position, encodeItemRef$1(op.referenceItem), op.items] ]; if (op.type === "assign") return ["patch", "assign", id, path, [op.value]]; if (op.type === "unassign") return ["patch", "assign", id, path, [op.keys]]; if (op.type === "replace") return [ "patch", "replace", id, path, [encodeItemRef$1(op.referenceItem), op.items] ]; if (op.type === "truncate") return ["patch", "truncate", id, path, [op.startIndex, op.endIndex]]; throw new Error(`Invalid operation type: ${op.type}`); } function maybeAddRevision(revision, mut) { const [mutType, patchType, id, path, args] = mut; return revision ? [mutType, patchType, id, path, args, revision] : mut; } var index$1 = /* @__PURE__ */ Object.freeze({ __proto__: null, decode, encode: encode$1 }); function encode(mutation) { return encodeMutation$1(mutation); } function encodeAll(mutations) { return mutations.flatMap(encode); } function encodeTransaction(transaction) { return { transactionId: transaction.id, mutations: encodeAll(transaction.mutations) }; } function encodeMutation$1(mutation) { var _a; if (mutation.type === "create" || mutation.type === "createIfNotExists" || mutation.type === "createOrReplace") return { [mutation.type]: mutation.document }; if (mutation.type === "delete") return { delete: { id: mutation.id } }; const ifRevisionID = (_a = mutation.options) == null ? void 0 : _a.ifRevision; return mutation.patches.map((patch2) => ({ patch: { id: mutation.id, ...ifRevisionID && { ifRevisionID }, ...patchToSanity(patch2) } })); } function patchToSanity(patch2) { const { path, op } = patch2; if (op.type === "unset") return { unset: [stringify(path)] }; if (op.type === "insert") return { insert: { [op.position]: stringify([...path, op.referenceItem]), items: op.items } }; if (op.type === "diffMatchPatch") return { diffMatchPatch: { [stringify(path)]: op.value } }; if (op.type === "inc") return { inc: { [stringify(path)]: op.amount } }; if (op.type === "dec") return { dec: { [stringify(path)]: op.amount } }; if (op.type === "set" || op.type === "setIfMissing") return { [op.type]: { [stringify(path)]: op.value } }; if (op.type === "truncate") { const range = [ op.startIndex, typeof op.endIndex == "number" ? op.endIndex : "" ].join(":"); return { unset: [`${stringify(path)}[${range}]`] }; } if (op.type === "upsert") return { unset: op.items.map( (item) => stringify([...path, { _key: item._key }]) ), insert: { [op.position]: stringify([...path, op.referenceItem]), items: op.items } }; if (op.type === "assign") return { set: Object.fromEntries( Object.keys(op.value).map((key) => [ stringify(path.concat(key)), op.value[key] ]) ) }; if (op.type === "unassign") return { unset: op.keys.map((key) => stringify(path.concat(key))) }; if (op.type === "replace") return { insert: { replace: stringify(path.concat(op.referenceItem)), items: op.items } }; throw new Error(`Unknown operation type ${op.type}`); } var index = /* @__PURE__ */ Object.freeze({ __proto__: null, decode: decode$1, decodeAll, encode, encodeAll, encodeMutation: encodeMutation$1, encodeTransaction }); function format(mutations) { return mutations.flatMap((m) => encodeMutation(m)).join(` `); } function encodeItemRef(ref) { return typeof ref == "number" ? ref : ref._key; } function encodeMutation(mutation) { var _a; if (mutation.type === "create" || mutation.type === "createIfNotExists" || mutation.type === "createOrReplace") return [mutation.type, ": ", JSON.stringify(mutation.document)].join(""); if (mutation.type === "delete") return ["delete ", mutation.id].join(": "); if (mutation.type === "patch") { const ifRevision = (_a = mutation.options) == null ? void 0 : _a.ifRevision; return [ "patch", " ", `id=${mutation.id}`, ifRevision ? ` (if revision==${ifRevision})` : "", `: `, mutation.patches.map((nodePatch) => ` ${formatPatchMutation(nodePatch)}`).join(` `) ].join(""); } throw new Error(`Invalid mutation type: ${mutation.type}`); } function formatPatchMutation(patch2) { const { op } = patch2, path = stringify(patch2.path); if (op.type === "unset") return [path, "unset()"].join(": "); if (op.type === "diffMatchPatch") return [path, `diffMatchPatch(${op.value})`].join(": "); if (op.type === "inc" || op.type === "dec") return [path, `${op.type}(${op.amount})`].join(": "); if (op.type === "set" || op.type === "setIfMissing") return [path, `${op.type}(${JSON.stringify(op.value)})`].join(": "); if (op.type === "assign") return [path, `${op.type}(${JSON.stringify(op.value)})`].join(": "); if (op.type === "unassign") return [path, `${op.type}(${JSON.stringify(op.keys)})`].join(": "); if (op.type === "insert" || op.type === "upsert") return [ path, `${op.type}(${op.position}, ${encodeItemRef( op.referenceItem )}, ${JSON.stringify(op.items)})` ].join(": "); if (op.type === "replace") return [ path, `replace(${encodeItemRef(op.referenceItem)}, ${JSON.stringify( op.items )})` ].join(": "); if (op.type === "truncate") return [path, `truncate(${op.startIndex}, ${op.endIndex}`].join(": "); throw new Error(`Invalid operation type: ${op.type}`); } var compact = /* @__PURE__ */ Object.freeze({ __proto__: null, format }); const set = (value) => ({ type: "set", value }), assign = (value) => ({ type: "assign", value }), unassign = (keys) => ({ type: "unassign", keys }), setIfMissing = (value) => ({ type: "setIfMissing", value }), unset = () => ({ type: "unset" }), inc = (amount = 1) => ({ type: "inc", amount }), dec = (amount = 1) => ({ type: "dec", amount }), diffMatchPatch = (value) => ({ type: "diffMatchPatch", value }); function insert(items, position, indexOrReferenceItem) { return { type: "insert", referenceItem: indexOrReferenceItem, position, items: arrify(items) }; } function append(items) { return insert(items, "after", -1); } function prepend(items) { return insert(items, "before", 0); } function insertBefore(items, indexOrReferenceItem) { return insert(items, "before", indexOrReferenceItem); } const insertAfter = (items, indexOrReferenceItem) => insert(items, "after", indexOrReferenceItem); function truncate(startIndex, endIndex) { return { type: "truncate", startIndex, endIndex }; } function replace(items, referenceItem) { return { type: "replace", referenceItem, items: arrify(items) }; } function upsert(items, position, referenceItem) { return { type: "upsert", items: arrify(items), referenceItem, position }; } function autoKeys(generateKey) { const ensureKeys = createEnsureKeys(generateKey), insert$1 = (position, referenceItem, items) => insert(ensureKeys(items), position, referenceItem), upsert$1 = (items, position, referenceItem) => upsert(ensureKeys(items), position, referenceItem), replace$1 = (items, position, referenceItem) => replace(ensureKeys(items), referenceItem), insertBefore2 = (ref, items) => insert$1("before", ref, items); return { insert: insert$1, upsert: upsert$1, replace: replace$1, insertBefore: insertBefore2, prepend: (items) => insertBefore2(0, items), insertAfter: (ref, items) => insert$1("after", ref, items), append: (items) => insert$1("after", -1, items) }; } function hasKey(item) { return "_key" in item; } function createEnsureKeys(generateKey) { return (array) => { let didModify = !1; const withKeys = array.map((item) => needsKey(item) ? (didModify = !0, { ...item, _key: generateKey(item) }) : item); return didModify ? withKeys : array; }; } function needsKey(arrayItem) { return isObject(arrayItem) && !hasKey(arrayItem); } function create(document) { return { type: "create", document }; } function patch(id, patches, options) { return { type: "patch", id, patches: arrify(patches), ...options ? { options } : {} }; } function at(path, operation) { return { path: typeof path == "string" ? parse(path) : path, op: operation }; } function createIfNotExists(document) { return { type: "createIfNotExists", document }; } function createOrReplace(document) { return { type: "createOrReplace", document }; } function delete_(id) { return { type: "delete", id }; } const del = delete_, destroy = delete_; export { index$1 as CompactEncoder, compact as CompactFormatter, index as SanityEncoder, append, assign, at, autoKeys, create, createIfNotExists, createOrReplace, dec, del, delete_, destroy, diffMatchPatch, inc, insert, insertAfter, insertBefore, patch, prepend, replace, set, setIfMissing, truncate, unassign, unset, upsert }; //# sourceMappingURL=index.esm.js.map