@powerhousedao/powerhouse-vetra-packages 6.2.2-dev.14 → 6.2.2-dev.16
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/dist/browser/assets/{entry-Cvoo4_c9.js → entry-PJ7Jewgi.js} +2 -2
- package/dist/browser/assets/{projection-entry-DVec8YRh.js → projection-entry-DI6tCI4R.js} +3 -3
- package/dist/browser/{connect-DSoIVHMW.js → connect-BjyXOuXJ.js} +4 -4
- package/dist/browser/{connect-DSoIVHMW.js.map → connect-BjyXOuXJ.js.map} +1 -1
- package/dist/browser/{dist-DMJv_4W0.js → dist-DrFQ11JR.js} +7 -6
- package/dist/browser/dist-DrFQ11JR.js.map +1 -0
- package/dist/browser/{document-drive-DYZGC0Dz.js → document-drive-BJ3S7Tuc.js} +561 -112
- package/dist/browser/document-drive-BJ3S7Tuc.js.map +1 -0
- package/dist/browser/document-models/index.js +1 -1
- package/dist/browser/{editor-sdV1WCg-.js → editor-DiltcAcB.js} +6 -6
- package/dist/browser/{editor-sdV1WCg-.js.map → editor-DiltcAcB.js.map} +1 -1
- package/dist/browser/{editor-Dsx-49N2.js → editor-nkPvitTX.js} +5 -5
- package/dist/browser/{editor-Dsx-49N2.js.map → editor-nkPvitTX.js.map} +1 -1
- package/dist/browser/editors/document-model-editor/module.js +1 -1
- package/dist/browser/editors/generic-drive-explorer/index.js +4 -4
- package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
- package/dist/browser/{folder-view-B-XELAhq.js → folder-view-DaWh_ZLU.js} +3 -3
- package/dist/browser/{folder-view-B-XELAhq.js.map → folder-view-DaWh_ZLU.js.map} +1 -1
- package/dist/browser/{graphql-editor-BuU1hB9h.js → graphql-editor-CLewUIZr.js} +3 -3
- package/dist/browser/{graphql-editor-BuU1hB9h.js.map → graphql-editor-CLewUIZr.js.map} +1 -1
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/{json-editor-CfSH58CC.js → json-editor-C-rxO4Mi.js} +3 -3
- package/dist/browser/{json-editor-CfSH58CC.js.map → json-editor-C-rxO4Mi.js.map} +1 -1
- package/dist/browser/{lib-CZuRjhln.js → lib-CdrAIBwG.js} +2 -2
- package/dist/browser/lib-CdrAIBwG.js.map +1 -0
- package/dist/browser/{state-schemas-BTb2-kMv.js → state-schemas-BOTYft7X.js} +3 -3
- package/dist/browser/{state-schemas-BTb2-kMv.js.map → state-schemas-BOTYft7X.js.map} +1 -1
- package/dist/node/{connect-DZxwsMOj.mjs → connect-BvY53UWP.mjs} +4 -4
- package/dist/node/{connect-DZxwsMOj.mjs.map → connect-BvY53UWP.mjs.map} +1 -1
- package/dist/node/{dist-BWxsIpdg.mjs → dist-BorJ6dO3.mjs} +7 -6
- package/dist/node/dist-BorJ6dO3.mjs.map +1 -0
- package/dist/node/{document-drive-DKHGrX9P.mjs → document-drive-CKlCgojv.mjs} +561 -112
- package/dist/node/document-drive-CKlCgojv.mjs.map +1 -0
- package/dist/node/document-models/index.mjs +1 -1
- package/dist/node/{editor-D43wDsdp.mjs → editor-B6xeXOnb.mjs} +6 -6
- package/dist/node/{editor-D43wDsdp.mjs.map → editor-B6xeXOnb.mjs.map} +1 -1
- package/dist/node/{editor-J7bEXv1X.mjs → editor-BMp6km6d.mjs} +5 -5
- package/dist/node/{editor-J7bEXv1X.mjs.map → editor-BMp6km6d.mjs.map} +1 -1
- package/dist/node/editors/document-model-editor/module.mjs +1 -1
- package/dist/node/editors/generic-drive-explorer/index.mjs +4 -4
- package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
- package/dist/node/{folder-view-CUWumU5-.mjs → folder-view-BQ3pm1uI.mjs} +3 -3
- package/dist/node/{folder-view-CUWumU5-.mjs.map → folder-view-BQ3pm1uI.mjs.map} +1 -1
- package/dist/node/{graphql-editor-DA-R6Qd0.mjs → graphql-editor-CNmYqxGe.mjs} +3 -3
- package/dist/node/{graphql-editor-DA-R6Qd0.mjs.map → graphql-editor-CNmYqxGe.mjs.map} +1 -1
- package/dist/node/index.mjs +2 -2
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/{json-editor-BHbwl235.mjs → json-editor-CPWkyWVo.mjs} +3 -3
- package/dist/node/{json-editor-BHbwl235.mjs.map → json-editor-CPWkyWVo.mjs.map} +1 -1
- package/dist/node/{main-DMZ7Ros2.mjs → main-Djluvvdu.mjs} +2 -2
- package/dist/node/main-Djluvvdu.mjs.map +1 -0
- package/dist/node/{state-schemas-C1K6Xug7.mjs → state-schemas-BqLT0vQR.mjs} +3 -3
- package/dist/node/{state-schemas-C1K6Xug7.mjs.map → state-schemas-BqLT0vQR.mjs.map} +1 -1
- package/package.json +6 -6
- package/dist/browser/dist-DMJv_4W0.js.map +0 -1
- package/dist/browser/document-drive-DYZGC0Dz.js.map +0 -1
- package/dist/browser/lib-CZuRjhln.js.map +0 -1
- package/dist/node/dist-BWxsIpdg.mjs.map +0 -1
- package/dist/node/document-drive-DKHGrX9P.mjs.map +0 -1
- package/dist/node/main-DMZ7Ros2.mjs.map +0 -1
|
@@ -183,7 +183,7 @@ function isBE() {
|
|
|
183
183
|
return new Uint8Array(new Uint16Array([65279]).buffer)[0] === 254;
|
|
184
184
|
}
|
|
185
185
|
//#endregion
|
|
186
|
-
//#region ../shared/dist/utils-
|
|
186
|
+
//#region ../shared/dist/utils-CTt1XRn-.js
|
|
187
187
|
const hashBrowser = (data, algorithm = "sha1", encoding = "base64", _params) => {
|
|
188
188
|
if (!["sha1"].includes(algorithm)) throw new Error(`Hashing algorithm not supported: "${algorithm}". Available: sha1`);
|
|
189
189
|
if (!["base64", "hex"].includes(encoding)) throw new Error(`Hash encoding not supported: "${encoding}". Available: base64, hex`);
|
|
@@ -230,6 +230,40 @@ function ab2hex(ab) {
|
|
|
230
230
|
const view = ArrayBuffer.isView(ab) ? ab : new Uint8Array(ab);
|
|
231
231
|
return Array.prototype.map.call(view, (x) => ("00" + x.toString(16)).slice(-2)).join("");
|
|
232
232
|
}
|
|
233
|
+
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
234
|
+
/**
|
|
235
|
+
* Decodes a base58btc (Bitcoin/IPFS alphabet) string to bytes. Returns null on
|
|
236
|
+
* any character outside the alphabet.
|
|
237
|
+
*/
|
|
238
|
+
function base58Decode(input) {
|
|
239
|
+
const bytes = [];
|
|
240
|
+
for (const ch of input) {
|
|
241
|
+
let carry = BASE58_ALPHABET.indexOf(ch);
|
|
242
|
+
if (carry === -1) return null;
|
|
243
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
244
|
+
carry += bytes[i] * 58;
|
|
245
|
+
bytes[i] = carry & 255;
|
|
246
|
+
carry >>= 8;
|
|
247
|
+
}
|
|
248
|
+
while (carry > 0) {
|
|
249
|
+
bytes.push(carry & 255);
|
|
250
|
+
carry >>= 8;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
for (let k = 0; k < input.length && input[k] === "1"; k++) bytes.push(0);
|
|
254
|
+
return Uint8Array.from(bytes.reverse());
|
|
255
|
+
}
|
|
256
|
+
/** Decodes a base64url string to bytes (portable across node, browsers, workers). */
|
|
257
|
+
function base64UrlToBytes(input) {
|
|
258
|
+
const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
259
|
+
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
260
|
+
let binary;
|
|
261
|
+
if (typeof atob === "function") binary = atob(padded);
|
|
262
|
+
else binary = Buffer.from(padded, "base64").toString("binary");
|
|
263
|
+
const bytes = new Uint8Array(binary.length);
|
|
264
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
265
|
+
return bytes;
|
|
266
|
+
}
|
|
233
267
|
function generateId(method) {
|
|
234
268
|
if (method && method.toString() !== "UUIDv4") throw new Error(`Id generation method not supported: "${method.toString()}"`);
|
|
235
269
|
return globalThis.crypto.randomUUID();
|
|
@@ -2588,6 +2622,75 @@ var DowngradeNotSupportedError = class extends Error {
|
|
|
2588
2622
|
this.toVersion = toVersion;
|
|
2589
2623
|
}
|
|
2590
2624
|
};
|
|
2625
|
+
/**
|
|
2626
|
+
* Thrown when INITIALIZE_AUTH is applied to an already-initialized auth scope.
|
|
2627
|
+
* The genesis action is valid only at auth revision zero.
|
|
2628
|
+
*/
|
|
2629
|
+
var AuthAlreadyInitializedError = class extends Error {
|
|
2630
|
+
documentId;
|
|
2631
|
+
constructor(documentId) {
|
|
2632
|
+
super(`Auth scope already initialized for document ${documentId}: INITIALIZE_AUTH is valid only at auth revision zero`);
|
|
2633
|
+
this.name = "AuthAlreadyInitializedError";
|
|
2634
|
+
this.documentId = documentId;
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2637
|
+
/**
|
|
2638
|
+
* Thrown when INITIALIZE_AUTH is not signed by the document creator (its signer
|
|
2639
|
+
* does not match `header.sig.publicKey`), so it cannot set the auth policy.
|
|
2640
|
+
*/
|
|
2641
|
+
var AuthInitializerNotCreatorError = class extends Error {
|
|
2642
|
+
documentId;
|
|
2643
|
+
constructor(documentId) {
|
|
2644
|
+
super(`INITIALIZE_AUTH for document ${documentId} must be signed by the document creator`);
|
|
2645
|
+
this.name = "AuthInitializerNotCreatorError";
|
|
2646
|
+
this.documentId = documentId;
|
|
2647
|
+
}
|
|
2648
|
+
};
|
|
2649
|
+
/**
|
|
2650
|
+
* Thrown when INITIALIZE_AUTH carries a version below 1. Version 0 is reserved
|
|
2651
|
+
* for the uninitialized auth scope.
|
|
2652
|
+
*/
|
|
2653
|
+
var InvalidAuthVersionError = class extends Error {
|
|
2654
|
+
documentId;
|
|
2655
|
+
version;
|
|
2656
|
+
constructor(documentId, version) {
|
|
2657
|
+
super(`Invalid auth policy version ${version} for document ${documentId}: INITIALIZE_AUTH requires an integer version >= 1`);
|
|
2658
|
+
this.name = "InvalidAuthVersionError";
|
|
2659
|
+
this.documentId = documentId;
|
|
2660
|
+
this.version = version;
|
|
2661
|
+
}
|
|
2662
|
+
};
|
|
2663
|
+
/** Thrown when a duplicate would lose the source policy's version or creator binding. */
|
|
2664
|
+
var AuthPolicyNotPreservedError = class extends Error {
|
|
2665
|
+
documentId;
|
|
2666
|
+
constructor(documentId) {
|
|
2667
|
+
super(`Duplicating document ${documentId} would not preserve its auth policy: the copy loses the policy version or its creator binding`);
|
|
2668
|
+
this.name = "AuthPolicyNotPreservedError";
|
|
2669
|
+
this.documentId = documentId;
|
|
2670
|
+
}
|
|
2671
|
+
};
|
|
2672
|
+
/**
|
|
2673
|
+
* Thrown when a grant referenced by REMOVE_GRANT or MOVE_GRANT does not exist.
|
|
2674
|
+
*/
|
|
2675
|
+
var GrantNotFoundError = class extends Error {
|
|
2676
|
+
grantId;
|
|
2677
|
+
constructor(grantId) {
|
|
2678
|
+
super(`Grant not found in auth scope: ${grantId}`);
|
|
2679
|
+
this.name = "GrantNotFoundError";
|
|
2680
|
+
this.grantId = grantId;
|
|
2681
|
+
}
|
|
2682
|
+
};
|
|
2683
|
+
/**
|
|
2684
|
+
* Thrown when a disallowed action (UNDO, REDO, PRUNE) targets the auth scope.
|
|
2685
|
+
*/
|
|
2686
|
+
var AuthActionNotAllowedError = class extends Error {
|
|
2687
|
+
actionType;
|
|
2688
|
+
constructor(actionType) {
|
|
2689
|
+
super(`${actionType} is not permitted on the auth scope`);
|
|
2690
|
+
this.name = "AuthActionNotAllowedError";
|
|
2691
|
+
this.actionType = actionType;
|
|
2692
|
+
}
|
|
2693
|
+
};
|
|
2591
2694
|
var HashMismatchError = class extends Error {
|
|
2592
2695
|
_scope;
|
|
2593
2696
|
_document;
|
|
@@ -3419,6 +3522,189 @@ const actions = {
|
|
|
3419
3522
|
...baseActions,
|
|
3420
3523
|
...documentModelActions
|
|
3421
3524
|
};
|
|
3525
|
+
const documentModelDocumentType = "powerhouse/document-model";
|
|
3526
|
+
/**
|
|
3527
|
+
* Thrown when a grant violates the v1 validation rules. The message is stored
|
|
3528
|
+
* on error operations, so it must be a pure function of the input.
|
|
3529
|
+
*/
|
|
3530
|
+
var InvalidGrantError = class extends Error {
|
|
3531
|
+
grantId;
|
|
3532
|
+
constructor(grantId, problem) {
|
|
3533
|
+
super(`Invalid grant "${grantId}": ${problem}`);
|
|
3534
|
+
this.name = "InvalidGrantError";
|
|
3535
|
+
this.grantId = grantId;
|
|
3536
|
+
}
|
|
3537
|
+
};
|
|
3538
|
+
/** Thrown for a `{ group }` principal on a group document: references never chain. */
|
|
3539
|
+
var GroupPrincipalNotAllowedError = class extends Error {
|
|
3540
|
+
grantId;
|
|
3541
|
+
constructor(grantId) {
|
|
3542
|
+
super(`Grant "${grantId}" uses a group principal on a group document: a group's auth scope cannot reference other groups`);
|
|
3543
|
+
this.name = "GroupPrincipalNotAllowedError";
|
|
3544
|
+
this.grantId = grantId;
|
|
3545
|
+
}
|
|
3546
|
+
};
|
|
3547
|
+
const GRANT_KEYS = new Set([
|
|
3548
|
+
"id",
|
|
3549
|
+
"description",
|
|
3550
|
+
"effect",
|
|
3551
|
+
"principal",
|
|
3552
|
+
"capability",
|
|
3553
|
+
"where"
|
|
3554
|
+
]);
|
|
3555
|
+
const PRINCIPAL_KINDS = new Set([
|
|
3556
|
+
"anyone",
|
|
3557
|
+
"address",
|
|
3558
|
+
"group",
|
|
3559
|
+
"match"
|
|
3560
|
+
]);
|
|
3561
|
+
const COMPARISON_CONDITION_KINDS = new Set([
|
|
3562
|
+
"eq",
|
|
3563
|
+
"ne",
|
|
3564
|
+
"lt",
|
|
3565
|
+
"lte",
|
|
3566
|
+
"gt",
|
|
3567
|
+
"gte"
|
|
3568
|
+
]);
|
|
3569
|
+
function isPlainValue(value) {
|
|
3570
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3571
|
+
}
|
|
3572
|
+
function operandProblem(value, capabilityScope, budget) {
|
|
3573
|
+
budget.nodes -= 1;
|
|
3574
|
+
if (budget.nodes < 0) return `condition exceeds 100 nodes`;
|
|
3575
|
+
if (!isPlainValue(value)) return "operand must be an object";
|
|
3576
|
+
const keys = Object.keys(value);
|
|
3577
|
+
if (keys.length !== 1) return "operand must have exactly one of attr or lit";
|
|
3578
|
+
if (keys[0] === "attr") {
|
|
3579
|
+
const attr = value.attr;
|
|
3580
|
+
if (typeof attr !== "string" || attr.length === 0) return "attr must be a non-empty string";
|
|
3581
|
+
if (capabilityScope !== void 0 && capabilityScope !== "*" && attr.startsWith("doc.")) {
|
|
3582
|
+
const pathScope = attr.split(".")[1] ?? "";
|
|
3583
|
+
if (pathScope !== capabilityScope) return `condition path "${attr}" reads scope "${pathScope}" but the capability covers only scope "${capabilityScope}"`;
|
|
3584
|
+
}
|
|
3585
|
+
return null;
|
|
3586
|
+
}
|
|
3587
|
+
if (keys[0] === "lit") {
|
|
3588
|
+
const lit = value.lit;
|
|
3589
|
+
if (lit !== null && typeof lit !== "string" && typeof lit !== "number" && typeof lit !== "boolean") return "lit must be a string, number, boolean, or null";
|
|
3590
|
+
if (typeof lit === "number" && !Number.isFinite(lit)) return "lit must be a finite number";
|
|
3591
|
+
if (typeof lit === "number" && Object.is(lit, -0)) return "lit must not be negative zero";
|
|
3592
|
+
return null;
|
|
3593
|
+
}
|
|
3594
|
+
return `unknown operand kind "${keys[0]}"`;
|
|
3595
|
+
}
|
|
3596
|
+
function conditionProblem(value, capabilityScope, depth, budget) {
|
|
3597
|
+
if (depth > 10) return `condition exceeds depth 10`;
|
|
3598
|
+
budget.nodes -= 1;
|
|
3599
|
+
if (budget.nodes < 0) return `condition exceeds 100 nodes`;
|
|
3600
|
+
if (!isPlainValue(value)) return "condition must be an object";
|
|
3601
|
+
const keys = Object.keys(value);
|
|
3602
|
+
if (keys.length !== 1) return "condition must have exactly one operator";
|
|
3603
|
+
const kind = keys[0];
|
|
3604
|
+
const body = value[kind];
|
|
3605
|
+
if (COMPARISON_CONDITION_KINDS.has(kind)) {
|
|
3606
|
+
if (!Array.isArray(body) || body.length !== 2) return `${kind} requires a pair of operands`;
|
|
3607
|
+
for (const operand of body) {
|
|
3608
|
+
const problem = operandProblem(operand, capabilityScope, budget);
|
|
3609
|
+
if (problem !== null) return problem;
|
|
3610
|
+
}
|
|
3611
|
+
return null;
|
|
3612
|
+
}
|
|
3613
|
+
if (kind === "in" || kind === "notIn") {
|
|
3614
|
+
if (!Array.isArray(body) || body.length !== 2 || !Array.isArray(body[1])) return `${kind} requires an operand and an operand list`;
|
|
3615
|
+
const first = operandProblem(body[0], capabilityScope, budget);
|
|
3616
|
+
if (first !== null) return first;
|
|
3617
|
+
for (const operand of body[1]) {
|
|
3618
|
+
const problem = operandProblem(operand, capabilityScope, budget);
|
|
3619
|
+
if (problem !== null) return problem;
|
|
3620
|
+
}
|
|
3621
|
+
return null;
|
|
3622
|
+
}
|
|
3623
|
+
if (kind === "exists") return operandProblem(body, capabilityScope, budget);
|
|
3624
|
+
if (kind === "and" || kind === "or") {
|
|
3625
|
+
if (!Array.isArray(body)) return `${kind} requires a condition list`;
|
|
3626
|
+
for (const child of body) {
|
|
3627
|
+
const problem = conditionProblem(child, capabilityScope, depth + 1, budget);
|
|
3628
|
+
if (problem !== null) return problem;
|
|
3629
|
+
}
|
|
3630
|
+
return null;
|
|
3631
|
+
}
|
|
3632
|
+
if (kind === "not") return conditionProblem(body, capabilityScope, depth + 1, budget);
|
|
3633
|
+
return `unknown condition operator "${kind}"`;
|
|
3634
|
+
}
|
|
3635
|
+
function principalProblem(value, capabilityScope) {
|
|
3636
|
+
if (!isPlainValue(value)) return "principal must be an object";
|
|
3637
|
+
const keys = Object.keys(value);
|
|
3638
|
+
if (keys.length !== 1 || !PRINCIPAL_KINDS.has(keys[0])) return "principal must have exactly one of anyone, address, group, or match";
|
|
3639
|
+
const kind = keys[0];
|
|
3640
|
+
if (kind === "anyone" && value.anyone !== true) return "anyone must be true";
|
|
3641
|
+
if (kind === "address") {
|
|
3642
|
+
const address = value.address;
|
|
3643
|
+
if (typeof address !== "string" || address.length === 0) return "address must be a non-empty string";
|
|
3644
|
+
}
|
|
3645
|
+
if (kind === "group") {
|
|
3646
|
+
const group = value.group;
|
|
3647
|
+
if (typeof group !== "string" || group.length === 0) return "group must be a non-empty string";
|
|
3648
|
+
}
|
|
3649
|
+
if (kind === "match") return conditionProblem(value.match, capabilityScope, 1, { nodes: 100 });
|
|
3650
|
+
return null;
|
|
3651
|
+
}
|
|
3652
|
+
function capabilityProblem(value) {
|
|
3653
|
+
if (!isPlainValue(value)) return "capability must be an object";
|
|
3654
|
+
const can = value.can;
|
|
3655
|
+
if (can !== "read" && can !== "execute") return "capability.can must be read or execute";
|
|
3656
|
+
const allowedKeys = can === "execute" ? [
|
|
3657
|
+
"can",
|
|
3658
|
+
"scope",
|
|
3659
|
+
"operation"
|
|
3660
|
+
] : ["can", "scope"];
|
|
3661
|
+
const unknownKeys = Object.keys(value).filter((key) => !allowedKeys.includes(key)).sort();
|
|
3662
|
+
if (unknownKeys.length > 0) return `unknown capability key "${unknownKeys[0]}"`;
|
|
3663
|
+
if (value.scope !== void 0) {
|
|
3664
|
+
if (typeof value.scope !== "string" || value.scope.length === 0) return "capability.scope must be a non-empty string";
|
|
3665
|
+
}
|
|
3666
|
+
if (can === "execute" && value.operation !== void 0) {
|
|
3667
|
+
const operation = value.operation;
|
|
3668
|
+
if (!Array.isArray(operation)) return "capability.operation must be an array";
|
|
3669
|
+
if (operation.length > 100) return `capability.operation exceeds 100 entries`;
|
|
3670
|
+
for (const entry of operation) if (typeof entry !== "string" || entry.length === 0) return "capability.operation entries must be non-empty strings";
|
|
3671
|
+
}
|
|
3672
|
+
return null;
|
|
3673
|
+
}
|
|
3674
|
+
/** Returns the first v1-rule violation, or null. Pure, total, deterministic. */
|
|
3675
|
+
function grantProblem(value) {
|
|
3676
|
+
if (!isPlainValue(value)) return "grant must be an object";
|
|
3677
|
+
const unknownKeys = Object.keys(value).filter((key) => !GRANT_KEYS.has(key)).sort();
|
|
3678
|
+
if (unknownKeys.length > 0) return `unknown grant key "${unknownKeys[0]}"`;
|
|
3679
|
+
if (typeof value.id !== "string" || value.id.length === 0) return "id must be a non-empty string";
|
|
3680
|
+
if (typeof value.description !== "string") return "description must be a string";
|
|
3681
|
+
if (value.effect !== "allow" && value.effect !== "deny") return "effect must be allow or deny";
|
|
3682
|
+
const capabilityValue = value.capability;
|
|
3683
|
+
const capability = capabilityProblem(capabilityValue);
|
|
3684
|
+
if (capability !== null) return capability;
|
|
3685
|
+
const capabilityScope = capabilityValue.scope;
|
|
3686
|
+
const principal = principalProblem(value.principal, capabilityScope);
|
|
3687
|
+
if (principal !== null) return principal;
|
|
3688
|
+
if (value.where !== void 0) return conditionProblem(value.where, capabilityScope, 1, { nodes: 100 });
|
|
3689
|
+
return null;
|
|
3690
|
+
}
|
|
3691
|
+
/** V1 shape rules plus the group-document group-principal ban. */
|
|
3692
|
+
function assertValidGrant(grant, documentType) {
|
|
3693
|
+
const grantId = isPlainValue(grant) && typeof grant.id === "string" ? grant.id : "";
|
|
3694
|
+
const problem = grantProblem(grant);
|
|
3695
|
+
if (problem !== null) throw new InvalidGrantError(grantId, problem);
|
|
3696
|
+
if (documentType === "@powerhousedao/document-group" && "group" in grant.principal) throw new GroupPrincipalNotAllowedError(grantId);
|
|
3697
|
+
}
|
|
3698
|
+
/** Validates an initial grant list: the count cap plus every grant. */
|
|
3699
|
+
function assertValidInitialGrants(grants, documentType) {
|
|
3700
|
+
if (grants.length > 100) throw new InvalidGrantError("", `policy exceeds 100 grants`);
|
|
3701
|
+
for (const grant of grants) assertValidGrant(grant, documentType);
|
|
3702
|
+
}
|
|
3703
|
+
/** Validates a grant upsert: the grant itself plus the count cap on append. */
|
|
3704
|
+
function assertValidGrantUpsert(grant, existing, documentType) {
|
|
3705
|
+
assertValidGrant(grant, documentType);
|
|
3706
|
+
if (!existing.some((g) => g.id === grant.id) && existing.length >= 100) throw new InvalidGrantError(grant.id, `policy exceeds 100 grants`);
|
|
3707
|
+
}
|
|
3422
3708
|
const documentModelFileExtension = "phdm";
|
|
3423
3709
|
const documentModelInitialLocalState = {};
|
|
3424
3710
|
const documentModelInitialGlobalState = {
|
|
@@ -4000,7 +4286,252 @@ const documentModelGlobalState = {
|
|
|
4000
4286
|
};
|
|
4001
4287
|
const HASH_ALGORITHM_SHA1 = "sha1";
|
|
4002
4288
|
const HASH_ENCODING_BASE64 = "base64";
|
|
4003
|
-
|
|
4289
|
+
/**
|
|
4290
|
+
* Creates a default PHAuthState
|
|
4291
|
+
*/
|
|
4292
|
+
function defaultAuthState() {
|
|
4293
|
+
return {
|
|
4294
|
+
version: 0,
|
|
4295
|
+
grants: []
|
|
4296
|
+
};
|
|
4297
|
+
}
|
|
4298
|
+
/**
|
|
4299
|
+
* Creates a default PHDocumentState
|
|
4300
|
+
*/
|
|
4301
|
+
function defaultDocumentState() {
|
|
4302
|
+
return {
|
|
4303
|
+
version: 0,
|
|
4304
|
+
hash: {
|
|
4305
|
+
algorithm: HASH_ALGORITHM_SHA1,
|
|
4306
|
+
encoding: HASH_ENCODING_BASE64
|
|
4307
|
+
}
|
|
4308
|
+
};
|
|
4309
|
+
}
|
|
4310
|
+
/**
|
|
4311
|
+
* Creates a default PHBaseState with auth and document properties
|
|
4312
|
+
*/
|
|
4313
|
+
function defaultBaseState() {
|
|
4314
|
+
return {
|
|
4315
|
+
auth: defaultAuthState(),
|
|
4316
|
+
document: defaultDocumentState()
|
|
4317
|
+
};
|
|
4318
|
+
}
|
|
4319
|
+
/**
|
|
4320
|
+
* Creates a PHAuthState with the given properties
|
|
4321
|
+
*/
|
|
4322
|
+
function createAuthState(auth) {
|
|
4323
|
+
return {
|
|
4324
|
+
...defaultAuthState(),
|
|
4325
|
+
...auth
|
|
4326
|
+
};
|
|
4327
|
+
}
|
|
4328
|
+
/**
|
|
4329
|
+
* Creates a PHDocumentState with the given properties
|
|
4330
|
+
*/
|
|
4331
|
+
function createDocumentState(document) {
|
|
4332
|
+
return {
|
|
4333
|
+
...defaultDocumentState(),
|
|
4334
|
+
...document
|
|
4335
|
+
};
|
|
4336
|
+
}
|
|
4337
|
+
/**
|
|
4338
|
+
* Creates a PHBaseState with the given auth and document properties
|
|
4339
|
+
*/
|
|
4340
|
+
function createBaseState(auth, document) {
|
|
4341
|
+
return {
|
|
4342
|
+
auth: createAuthState(auth),
|
|
4343
|
+
document: createDocumentState(document)
|
|
4344
|
+
};
|
|
4345
|
+
}
|
|
4346
|
+
/**
|
|
4347
|
+
* Backfills the auth scope to the default for legacy documents serialized with
|
|
4348
|
+
* an empty `auth`. Replaces only `state.auth`. Idempotent.
|
|
4349
|
+
*/
|
|
4350
|
+
function backfillAuthState(state) {
|
|
4351
|
+
return {
|
|
4352
|
+
...state,
|
|
4353
|
+
auth: createAuthState(state.auth)
|
|
4354
|
+
};
|
|
4355
|
+
}
|
|
4356
|
+
function defaultGlobalState() {
|
|
4357
|
+
return {
|
|
4358
|
+
...defaultBaseState(),
|
|
4359
|
+
author: {
|
|
4360
|
+
name: "",
|
|
4361
|
+
website: ""
|
|
4362
|
+
},
|
|
4363
|
+
description: "",
|
|
4364
|
+
extension: "",
|
|
4365
|
+
id: "",
|
|
4366
|
+
name: "",
|
|
4367
|
+
specifications: []
|
|
4368
|
+
};
|
|
4369
|
+
}
|
|
4370
|
+
function defaultLocalState() {
|
|
4371
|
+
return {};
|
|
4372
|
+
}
|
|
4373
|
+
function createGlobalState(state) {
|
|
4374
|
+
return {
|
|
4375
|
+
...defaultGlobalState(),
|
|
4376
|
+
...state || {}
|
|
4377
|
+
};
|
|
4378
|
+
}
|
|
4379
|
+
function createLocalState(state) {
|
|
4380
|
+
return {
|
|
4381
|
+
...defaultLocalState(),
|
|
4382
|
+
...state || {}
|
|
4383
|
+
};
|
|
4384
|
+
}
|
|
4385
|
+
function createState(baseState, globalState, localState) {
|
|
4386
|
+
return {
|
|
4387
|
+
...createBaseState(baseState?.auth, baseState?.document),
|
|
4388
|
+
global: createGlobalState(globalState),
|
|
4389
|
+
local: createLocalState(localState)
|
|
4390
|
+
};
|
|
4391
|
+
}
|
|
4392
|
+
/**
|
|
4393
|
+
* Destructuring a null input (reachable via raw synced operations) would
|
|
4394
|
+
* store an engine-specific TypeError message on the error operation.
|
|
4395
|
+
*/
|
|
4396
|
+
function assertActionInputShape(input) {
|
|
4397
|
+
if (!isPlainValue(input)) throw new InvalidActionInputError({ input: "must be an object" });
|
|
4398
|
+
}
|
|
4399
|
+
function withGrants(document, grants) {
|
|
4400
|
+
return {
|
|
4401
|
+
...document,
|
|
4402
|
+
state: {
|
|
4403
|
+
...document.state,
|
|
4404
|
+
auth: {
|
|
4405
|
+
...document.state.auth,
|
|
4406
|
+
grants
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
};
|
|
4410
|
+
}
|
|
4411
|
+
const P256_PUBKEY_MULTICODEC = [128, 36];
|
|
4412
|
+
const DID_KEY_PREFIX = "did:key:z";
|
|
4413
|
+
function bytesEqual(a, b) {
|
|
4414
|
+
if (a.length !== b.length) return false;
|
|
4415
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
4416
|
+
return true;
|
|
4417
|
+
}
|
|
4418
|
+
/**
|
|
4419
|
+
* True when `signerKey` (an ActionSigner app key, a did:key) identifies the same
|
|
4420
|
+
* key recorded as the document creator. Returns false
|
|
4421
|
+
* when there is no creator (empty JWK) or no signer key.
|
|
4422
|
+
*/
|
|
4423
|
+
function isDocumentCreator(creatorKey, signerKey) {
|
|
4424
|
+
if (!creatorKey?.x || !creatorKey.y) return false;
|
|
4425
|
+
if (!signerKey || !signerKey.startsWith(DID_KEY_PREFIX)) return false;
|
|
4426
|
+
const decoded = base58Decode(signerKey.slice(9));
|
|
4427
|
+
if (!decoded || decoded.length !== 35) return false;
|
|
4428
|
+
if (decoded[0] !== P256_PUBKEY_MULTICODEC[0] || decoded[1] !== P256_PUBKEY_MULTICODEC[1]) return false;
|
|
4429
|
+
const parityPrefix = decoded[2];
|
|
4430
|
+
if (parityPrefix !== 2 && parityPrefix !== 3) return false;
|
|
4431
|
+
const didX = decoded.subarray(3, 35);
|
|
4432
|
+
const jwkX = base64UrlToBytes(creatorKey.x);
|
|
4433
|
+
const jwkY = base64UrlToBytes(creatorKey.y);
|
|
4434
|
+
if (jwkX.length !== 32 || jwkY.length !== 32) return false;
|
|
4435
|
+
if (!bytesEqual(didX, jwkX)) return false;
|
|
4436
|
+
return (jwkY[31] & 1) === 1 === (parityPrefix === 3);
|
|
4437
|
+
}
|
|
4438
|
+
/**
|
|
4439
|
+
* Sets the initial policy. Valid only while the auth scope is uninitialized
|
|
4440
|
+
* (version 0). The input version is the policy language version and must be an
|
|
4441
|
+
* integer >= 1; 0 is reserved for the uninitialized state. On a signed-header
|
|
4442
|
+
* document it must be signed by the document creator (`header.sig.publicKey`).
|
|
4443
|
+
*/
|
|
4444
|
+
function applyInitializeAuthAction(document, action) {
|
|
4445
|
+
assertActionInputShape(action.input);
|
|
4446
|
+
const { version, grants } = action.input;
|
|
4447
|
+
if (!Number.isInteger(version) || version < 1) throw new InvalidAuthVersionError(document.header.id, version);
|
|
4448
|
+
if (document.state.auth.version !== 0) throw new AuthAlreadyInitializedError(document.header.id);
|
|
4449
|
+
if (!Array.isArray(grants)) throw new InvalidActionInputError({ grants: "must be an array" });
|
|
4450
|
+
assertValidInitialGrants(grants, document.header.documentType);
|
|
4451
|
+
const creatorKey = document.header.sig.publicKey;
|
|
4452
|
+
const signerKey = action.context?.signer?.app.key;
|
|
4453
|
+
const hasCreator = Boolean(creatorKey.kty || creatorKey.x || creatorKey.y);
|
|
4454
|
+
if (hasCreator && !isDocumentCreator(creatorKey, signerKey)) throw new AuthInitializerNotCreatorError(document.header.id);
|
|
4455
|
+
const creator = hasCreator ? signerKey : void 0;
|
|
4456
|
+
return {
|
|
4457
|
+
...document,
|
|
4458
|
+
state: {
|
|
4459
|
+
...document.state,
|
|
4460
|
+
auth: createAuthState(creator ? {
|
|
4461
|
+
version,
|
|
4462
|
+
grants,
|
|
4463
|
+
creator
|
|
4464
|
+
} : {
|
|
4465
|
+
version,
|
|
4466
|
+
grants
|
|
4467
|
+
})
|
|
4468
|
+
}
|
|
4469
|
+
};
|
|
4470
|
+
}
|
|
4471
|
+
/** Upserts a grant by id: replaces in place if present, otherwise appends. */
|
|
4472
|
+
function applySetGrantAction(document, action) {
|
|
4473
|
+
assertActionInputShape(action.input);
|
|
4474
|
+
const { grant } = action.input;
|
|
4475
|
+
const grants = document.state.auth.grants;
|
|
4476
|
+
assertValidGrantUpsert(grant, grants, document.header.documentType);
|
|
4477
|
+
return withGrants(document, grants.some((g) => g.id === grant.id) ? grants.map((g) => g.id === grant.id ? grant : g) : [...grants, grant]);
|
|
4478
|
+
}
|
|
4479
|
+
/** Removes a grant by id; throws if the id is not present. */
|
|
4480
|
+
function applyRemoveGrantAction(document, action) {
|
|
4481
|
+
assertActionInputShape(action.input);
|
|
4482
|
+
const { id } = action.input;
|
|
4483
|
+
const grants = document.state.auth.grants;
|
|
4484
|
+
if (!grants.some((g) => g.id === id)) throw new GrantNotFoundError(id);
|
|
4485
|
+
return withGrants(document, grants.filter((g) => g.id !== id));
|
|
4486
|
+
}
|
|
4487
|
+
/**
|
|
4488
|
+
* Moves a grant by id to a new index. Order is load-bearing (the last
|
|
4489
|
+
* applicable grant wins), so the relative order of the other grants is kept.
|
|
4490
|
+
* The target index is clamped to the valid range; an unknown id throws.
|
|
4491
|
+
*/
|
|
4492
|
+
function applyMoveGrantAction(document, action) {
|
|
4493
|
+
assertActionInputShape(action.input);
|
|
4494
|
+
const { id, index } = action.input;
|
|
4495
|
+
const grants = document.state.auth.grants;
|
|
4496
|
+
const from = grants.findIndex((g) => g.id === id);
|
|
4497
|
+
if (from === -1) throw new GrantNotFoundError(id);
|
|
4498
|
+
const next = [...grants];
|
|
4499
|
+
const [moved] = next.splice(from, 1);
|
|
4500
|
+
const to = Math.max(0, Math.min(index, next.length));
|
|
4501
|
+
next.splice(to, 0, moved);
|
|
4502
|
+
return withGrants(document, next);
|
|
4503
|
+
}
|
|
4504
|
+
/**
|
|
4505
|
+
* Dispatches an auth-scope action to its handler. This is the auth scope's
|
|
4506
|
+
* dedicated reducer: it is applied by the base reducer instead of the model
|
|
4507
|
+
* reducer, mirroring the document-scope platform handlers. Unknown types are a
|
|
4508
|
+
* no-op, matching the model-reducer default.
|
|
4509
|
+
*/
|
|
4510
|
+
function applyAuthAction(document, action) {
|
|
4511
|
+
switch (action.type) {
|
|
4512
|
+
case "INITIALIZE_AUTH": return applyInitializeAuthAction(document, action);
|
|
4513
|
+
case "SET_GRANT": return applySetGrantAction(document, action);
|
|
4514
|
+
case "REMOVE_GRANT": return applyRemoveGrantAction(document, action);
|
|
4515
|
+
case "MOVE_GRANT": return applyMoveGrantAction(document, action);
|
|
4516
|
+
default: return document;
|
|
4517
|
+
}
|
|
4518
|
+
}
|
|
4519
|
+
/**
|
|
4520
|
+
* Because only creators can initialize auth scopes, we must verify that either
|
|
4521
|
+
* the document has no auth or the version and creator match.
|
|
4522
|
+
*/
|
|
4523
|
+
function assertAuthPreservedOnDuplicate(documentId, source, duplicated) {
|
|
4524
|
+
if (!source || source.version === 0) return;
|
|
4525
|
+
if (duplicated === void 0 || duplicated.version !== source.version || duplicated.creator !== source.creator) throw new AuthPolicyNotPreservedError(documentId);
|
|
4526
|
+
}
|
|
4527
|
+
/** UNDO, REDO and PRUNE are rejected on the auth scope. */
|
|
4528
|
+
function assertAuthScopeActionAllowed(action) {
|
|
4529
|
+
if (action.scope === "auth" && [
|
|
4530
|
+
"UNDO",
|
|
4531
|
+
"REDO",
|
|
4532
|
+
"PRUNE"
|
|
4533
|
+
].includes(action.type)) throw new AuthActionNotAllowedError(action.type);
|
|
4534
|
+
}
|
|
4004
4535
|
const BaseDocumentHeaderSchema = object({
|
|
4005
4536
|
id: string(),
|
|
4006
4537
|
name: string(),
|
|
@@ -4172,7 +4703,8 @@ const defaultCreateState = (state) => {
|
|
|
4172
4703
|
};
|
|
4173
4704
|
function replayDocument(initialState, operations, reducer, header, dispatch, skipHeaderOperations = {}, options) {
|
|
4174
4705
|
const { checkHashes = true, reuseOperationResultingState, operationResultingStateParser = parseResultingState, skipIndexValidation } = options || {};
|
|
4175
|
-
|
|
4706
|
+
const backfilledInitialState = backfillAuthState(initialState);
|
|
4707
|
+
let documentState = backfilledInitialState;
|
|
4176
4708
|
const operationsToReplay = [];
|
|
4177
4709
|
const allScopes = new Set([
|
|
4178
4710
|
...Object.keys(operations),
|
|
@@ -4207,7 +4739,7 @@ function replayDocument(initialState, operations, reducer, header, dispatch, ski
|
|
|
4207
4739
|
const document = {
|
|
4208
4740
|
header,
|
|
4209
4741
|
state: defaultCreateState(documentState),
|
|
4210
|
-
initialState,
|
|
4742
|
+
initialState: backfilledInitialState,
|
|
4211
4743
|
operations: initialOperations,
|
|
4212
4744
|
clipboard: []
|
|
4213
4745
|
};
|
|
@@ -4500,7 +5032,7 @@ function loadStateOperation(document, action) {
|
|
|
4500
5032
|
...document.header,
|
|
4501
5033
|
name: action.state.name
|
|
4502
5034
|
},
|
|
4503
|
-
state: action.state.data
|
|
5035
|
+
state: backfillAuthState(action.state.data)
|
|
4504
5036
|
};
|
|
4505
5037
|
}
|
|
4506
5038
|
function replayOperations(initialState, clearedOperations, stateReducer, header, dispatch, documentReducer = baseReducer, skipHeaderOperations = {}, options) {
|
|
@@ -4674,6 +5206,7 @@ function processUndoOperation(document, scope, customReducer, reuseOperationResu
|
|
|
4674
5206
|
function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
4675
5207
|
const { skip, ignoreSkipOperations = false, reuseOperationResultingState = false, operationResultingStateParser, pruneOnSkip = true, branch = "main" } = options;
|
|
4676
5208
|
let _action = actionFromAction(action);
|
|
5209
|
+
assertAuthScopeActionAllowed(_action);
|
|
4677
5210
|
let skipValue = skip ?? options.replayOptions?.operation.skip ?? 0;
|
|
4678
5211
|
let newDocument = { ...document };
|
|
4679
5212
|
let reuseLastOperationIndex = false;
|
|
@@ -4721,6 +5254,13 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
|
4721
5254
|
}
|
|
4722
5255
|
newDocument = create(newDocument, (draft) => {
|
|
4723
5256
|
try {
|
|
5257
|
+
if (_action.scope === "auth") {
|
|
5258
|
+
const authState = applyAuthAction(newDocument, _action).state;
|
|
5259
|
+
unsafe(() => {
|
|
5260
|
+
draft.state = castDraft(authState);
|
|
5261
|
+
});
|
|
5262
|
+
return;
|
|
5263
|
+
}
|
|
4724
5264
|
const newState = customReducer(draft.state, _action, dispatch);
|
|
4725
5265
|
if (newState) unsafe(() => {
|
|
4726
5266
|
draft.state = castDraft(newState);
|
|
@@ -5514,10 +6054,10 @@ function applyInitialState(document, action) {
|
|
|
5514
6054
|
const input = action.input;
|
|
5515
6055
|
const newState = input.initialState || input.state;
|
|
5516
6056
|
if (newState) {
|
|
5517
|
-
document.state = {
|
|
6057
|
+
document.state = backfillAuthState({
|
|
5518
6058
|
...document.state,
|
|
5519
6059
|
...newState
|
|
5520
|
-
};
|
|
6060
|
+
});
|
|
5521
6061
|
document.initialState = document.state;
|
|
5522
6062
|
}
|
|
5523
6063
|
}
|
|
@@ -5577,7 +6117,6 @@ function computeUpgradeTransitions(manifest, fromVersion, toVersion) {
|
|
|
5577
6117
|
}
|
|
5578
6118
|
return transitions;
|
|
5579
6119
|
}
|
|
5580
|
-
const NON_DOMAIN_SCOPES$1 = new Set(["auth", "document"]);
|
|
5581
6120
|
function highestReducerVersion(reducers) {
|
|
5582
6121
|
const keys = Object.keys(reducers).map(Number);
|
|
5583
6122
|
if (keys.length === 0) throw new Error("VersionedReplayConfig.reducers must not be empty");
|
|
@@ -5609,11 +6148,11 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5609
6148
|
const spine = (operations["document"] ?? []).slice().sort((a, b) => a.index - b.index);
|
|
5610
6149
|
const upgrades = spine.filter((op) => op.action.type === "UPGRADE_DOCUMENT");
|
|
5611
6150
|
const legacyFallback = () => {
|
|
5612
|
-
const
|
|
6151
|
+
const replayOps = Object.fromEntries(Object.entries(operations).filter(([s]) => s !== "document"));
|
|
5613
6152
|
const latestVersion = highestReducerVersion(config.reducers);
|
|
5614
6153
|
const reducer = config.reducers[latestVersion];
|
|
5615
6154
|
return {
|
|
5616
|
-
...replayDocument(initialState,
|
|
6155
|
+
...replayDocument(initialState, replayOps, reducer, header, dispatch, {}, options),
|
|
5617
6156
|
operations
|
|
5618
6157
|
};
|
|
5619
6158
|
};
|
|
@@ -5637,14 +6176,14 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5637
6176
|
const a = op.action;
|
|
5638
6177
|
return a.input.fromVersion > 0 && a.input.fromVersion < a.input.toVersion;
|
|
5639
6178
|
});
|
|
5640
|
-
const
|
|
6179
|
+
const replayScopes = Object.keys(operations).filter((s) => s !== "document");
|
|
5641
6180
|
const scopeOps = {};
|
|
5642
|
-
for (const s of
|
|
6181
|
+
for (const s of replayScopes) scopeOps[s] = (operations[s] ?? []).slice().sort((a, b) => a.index - b.index);
|
|
5643
6182
|
const boundaries = validatedUpgrades.map((upgradeOp) => {
|
|
5644
6183
|
const revisionSnapshot = upgradeOp.action.input.revision;
|
|
5645
6184
|
const upgradeTimestamp = upgradeOp.timestampUtcMs;
|
|
5646
6185
|
const boundary = {};
|
|
5647
|
-
for (const s of
|
|
6186
|
+
for (const s of replayScopes) {
|
|
5648
6187
|
const ops = scopeOps[s] ?? [];
|
|
5649
6188
|
if (revisionSnapshot !== void 0) {
|
|
5650
6189
|
const rev = revisionSnapshot[s] ?? 0;
|
|
@@ -5662,7 +6201,7 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5662
6201
|
}
|
|
5663
6202
|
return boundary;
|
|
5664
6203
|
});
|
|
5665
|
-
for (let i = 1; i < boundaries.length; i++) for (const s of
|
|
6204
|
+
for (let i = 1; i < boundaries.length; i++) for (const s of replayScopes) {
|
|
5666
6205
|
const prev = boundaries[i - 1]?.[s] ?? 0;
|
|
5667
6206
|
const curr = boundaries[i]?.[s] ?? 0;
|
|
5668
6207
|
if (boundaries[i]) boundaries[i][s] = Math.max(prev, curr);
|
|
@@ -5674,10 +6213,11 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5674
6213
|
]);
|
|
5675
6214
|
const initialOperations = {};
|
|
5676
6215
|
for (const s of allScopes) initialOperations[s] = [];
|
|
6216
|
+
const backfilledSeed = backfillAuthState(seedState);
|
|
5677
6217
|
let document = {
|
|
5678
6218
|
header,
|
|
5679
|
-
state:
|
|
5680
|
-
initialState:
|
|
6219
|
+
state: backfilledSeed,
|
|
6220
|
+
initialState: backfilledSeed,
|
|
5681
6221
|
operations: initialOperations,
|
|
5682
6222
|
clipboard: []
|
|
5683
6223
|
};
|
|
@@ -5689,7 +6229,7 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5689
6229
|
const available = Object.keys(config.reducers).join(", ");
|
|
5690
6230
|
throw new Error(`No reducer registered for document version ${currentVersion}. Available versions: ${available}`);
|
|
5691
6231
|
}
|
|
5692
|
-
for (const s of
|
|
6232
|
+
for (const s of replayScopes) {
|
|
5693
6233
|
const ops = scopeOps[s] ?? [];
|
|
5694
6234
|
const segStart = k === 0 ? 0 : boundaries[k - 1]?.[s] ?? 0;
|
|
5695
6235
|
const segEnd = k < validatedUpgrades.length ? boundaries[k]?.[s] ?? ops.length : ops.length;
|
|
@@ -5742,7 +6282,7 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5742
6282
|
}
|
|
5743
6283
|
};
|
|
5744
6284
|
if (!checkHashes) {
|
|
5745
|
-
const allReplayedOps =
|
|
6285
|
+
const allReplayedOps = replayScopes.flatMap((s) => scopeOps[s] ?? []);
|
|
5746
6286
|
for (const scope of Object.keys(document.state)) {
|
|
5747
6287
|
const capturedHash = segmentEndHashPerScope.get(scope);
|
|
5748
6288
|
const scopeHash = capturedHash !== void 0 ? capturedHash : hashDocumentStateForScope(document, scope);
|
|
@@ -5784,7 +6324,6 @@ function replayDocumentVersioned(initialState, operations, config, header, dispa
|
|
|
5784
6324
|
}
|
|
5785
6325
|
};
|
|
5786
6326
|
}
|
|
5787
|
-
const NON_DOMAIN_SCOPES = new Set(["auth", "document"]);
|
|
5788
6327
|
function zipAsync(data) {
|
|
5789
6328
|
return new Promise((resolve, reject) => {
|
|
5790
6329
|
zip(data, (err, out) => err ? reject(err) : resolve(out));
|
|
@@ -5863,7 +6402,7 @@ async function parseZipData(data) {
|
|
|
5863
6402
|
async function loadFromZipData(data, reducer, options) {
|
|
5864
6403
|
const { initialState, header, clearedOperations } = await parseZipData(data);
|
|
5865
6404
|
return {
|
|
5866
|
-
...replayDocument(initialState, Object.fromEntries(Object.entries(clearedOperations).filter(([scope]) =>
|
|
6405
|
+
...replayDocument(initialState, Object.fromEntries(Object.entries(clearedOperations).filter(([scope]) => scope !== "document")), reducer, header, void 0, {}, options),
|
|
5867
6406
|
operations: clearedOperations
|
|
5868
6407
|
};
|
|
5869
6408
|
}
|
|
@@ -5886,96 +6425,6 @@ const documentModelLoadFromInput = (input) => {
|
|
|
5886
6425
|
const documentModelSaveToFileHandle = (document, input) => {
|
|
5887
6426
|
return baseSaveToFileHandle(document, input);
|
|
5888
6427
|
};
|
|
5889
|
-
/**
|
|
5890
|
-
* Creates a default PHAuthState
|
|
5891
|
-
*/
|
|
5892
|
-
function defaultAuthState() {
|
|
5893
|
-
return {};
|
|
5894
|
-
}
|
|
5895
|
-
/**
|
|
5896
|
-
* Creates a default PHDocumentState
|
|
5897
|
-
*/
|
|
5898
|
-
function defaultDocumentState() {
|
|
5899
|
-
return {
|
|
5900
|
-
version: 0,
|
|
5901
|
-
hash: {
|
|
5902
|
-
algorithm: HASH_ALGORITHM_SHA1,
|
|
5903
|
-
encoding: HASH_ENCODING_BASE64
|
|
5904
|
-
}
|
|
5905
|
-
};
|
|
5906
|
-
}
|
|
5907
|
-
/**
|
|
5908
|
-
* Creates a default PHBaseState with auth and document properties
|
|
5909
|
-
*/
|
|
5910
|
-
function defaultBaseState() {
|
|
5911
|
-
return {
|
|
5912
|
-
auth: defaultAuthState(),
|
|
5913
|
-
document: defaultDocumentState()
|
|
5914
|
-
};
|
|
5915
|
-
}
|
|
5916
|
-
/**
|
|
5917
|
-
* Creates a PHAuthState with the given properties
|
|
5918
|
-
*/
|
|
5919
|
-
function createAuthState(auth) {
|
|
5920
|
-
return {
|
|
5921
|
-
...defaultAuthState(),
|
|
5922
|
-
...auth
|
|
5923
|
-
};
|
|
5924
|
-
}
|
|
5925
|
-
/**
|
|
5926
|
-
* Creates a PHDocumentState with the given properties
|
|
5927
|
-
*/
|
|
5928
|
-
function createDocumentState(document) {
|
|
5929
|
-
return {
|
|
5930
|
-
...defaultDocumentState(),
|
|
5931
|
-
...document
|
|
5932
|
-
};
|
|
5933
|
-
}
|
|
5934
|
-
/**
|
|
5935
|
-
* Creates a PHBaseState with the given auth and document properties
|
|
5936
|
-
*/
|
|
5937
|
-
function createBaseState(auth, document) {
|
|
5938
|
-
return {
|
|
5939
|
-
auth: createAuthState(auth),
|
|
5940
|
-
document: createDocumentState(document)
|
|
5941
|
-
};
|
|
5942
|
-
}
|
|
5943
|
-
function defaultGlobalState() {
|
|
5944
|
-
return {
|
|
5945
|
-
...defaultBaseState(),
|
|
5946
|
-
author: {
|
|
5947
|
-
name: "",
|
|
5948
|
-
website: ""
|
|
5949
|
-
},
|
|
5950
|
-
description: "",
|
|
5951
|
-
extension: "",
|
|
5952
|
-
id: "",
|
|
5953
|
-
name: "",
|
|
5954
|
-
specifications: []
|
|
5955
|
-
};
|
|
5956
|
-
}
|
|
5957
|
-
function defaultLocalState() {
|
|
5958
|
-
return {};
|
|
5959
|
-
}
|
|
5960
|
-
function createGlobalState(state) {
|
|
5961
|
-
return {
|
|
5962
|
-
...defaultGlobalState(),
|
|
5963
|
-
...state || {}
|
|
5964
|
-
};
|
|
5965
|
-
}
|
|
5966
|
-
function createLocalState(state) {
|
|
5967
|
-
return {
|
|
5968
|
-
...defaultLocalState(),
|
|
5969
|
-
...state || {}
|
|
5970
|
-
};
|
|
5971
|
-
}
|
|
5972
|
-
function createState(baseState, globalState, localState) {
|
|
5973
|
-
return {
|
|
5974
|
-
...createBaseState(baseState?.auth, baseState?.document),
|
|
5975
|
-
global: createGlobalState(globalState),
|
|
5976
|
-
local: createLocalState(localState)
|
|
5977
|
-
};
|
|
5978
|
-
}
|
|
5979
6428
|
//#endregion
|
|
5980
6429
|
//#region ../document-model/dist/index.js
|
|
5981
6430
|
const isStateOfType$1 = (state) => {
|
|
@@ -7054,6 +7503,6 @@ const driveDocumentModelModule = {
|
|
|
7054
7503
|
}
|
|
7055
7504
|
};
|
|
7056
7505
|
//#endregion
|
|
7057
|
-
export {
|
|
7506
|
+
export { isDocumentAction as A, setModuleName as B, createState as C, deleteOperation as D, deleteModule as E, setInitialState as F, setOperationSchema as G, setOperationDescription as H, setModelDescription as I, validateInitialState as J, setStateSchema as K, setModelExtension as L, replayDocumentVersioned as M, setAuthorName as N, deleteOperationError as O, setAuthorWebsite as P, setModelId as R, createReducer as S, defaultBaseState as T, setOperationErrorName as U, setName as V, setOperationName as W, validateStateSchemaName as X, validateModules as Y, generateId as Z, baseLoadFromInput as _, handleTargetNameCollisions as a, buildSignedAction as b, moveNode as c, logger as d, addModule as f, baseCreateDocument as g, assertAuthPreservedOnDuplicate as h, generateNodesCopy as i, redo as j, documentModelDocumentType as k, updateNode as l, addOperationError as m, copyNode as n, isFileNode as o, addOperation as p, undo as q, driveDocumentModelModule as r, isFolderNode as s, addFolder as t, documentModelDocumentModelModule as u, baseLoadFromInputVersioned as v, createZip as w, createPresignedHeader as x, baseSaveToFileHandle as y, setModelName as z };
|
|
7058
7507
|
|
|
7059
|
-
//# sourceMappingURL=document-drive-
|
|
7508
|
+
//# sourceMappingURL=document-drive-CKlCgojv.mjs.map
|