@xnetjs/data 0.12.0 → 2.0.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.
Files changed (160) hide show
  1. package/dist/account-ZD3HMRY6.js +12 -0
  2. package/dist/{account-ledger-R2GAFJL6.js → account-ledger-ZHBNVREV.js} +3 -3
  3. package/dist/auth/index.d.ts +15 -5
  4. package/dist/auth/index.js +1 -1
  5. package/dist/budget-FTGZEXX6.js +12 -0
  6. package/dist/canvas-NQBTRNLS.js +10 -0
  7. package/dist/channel-474QAZGP.js +12 -0
  8. package/dist/chat-message-LGLCITLE.js +10 -0
  9. package/dist/checkpoint-MZHJ7PCZ.js +12 -0
  10. package/dist/{chunk-VQ7JHB67.js → chunk-22FKOLMX.js} +2 -2
  11. package/dist/{chunk-LYSWLCOI.js → chunk-26HTTVJN.js} +2 -2
  12. package/dist/{chunk-PH3PVAR6.js → chunk-3PV6QTKF.js} +2 -2
  13. package/dist/{chunk-KQUALW4O.js → chunk-4KJ4NAMC.js} +1 -1
  14. package/dist/{chunk-JFMLCFZJ.js → chunk-4S73XDWH.js} +585 -230
  15. package/dist/{chunk-U64CW73O.js → chunk-52DR23IW.js} +2 -2
  16. package/dist/{chunk-SVNGSZZA.js → chunk-57UZYV3L.js} +2 -2
  17. package/dist/{chunk-QVQVKZ3U.js → chunk-5UJMY3AH.js} +6 -5
  18. package/dist/chunk-6ZUJID52.js +41 -0
  19. package/dist/{chunk-3J3HILXO.js → chunk-7PCMTV6J.js} +2 -2
  20. package/dist/{chunk-YSUIXD2Y.js → chunk-C4CQH7UD.js} +2 -2
  21. package/dist/{chunk-PNESGUH5.js → chunk-D4EVJN2P.js} +2 -2
  22. package/dist/{chunk-RL64OJJ5.js → chunk-D4LUUZYD.js} +36 -9
  23. package/dist/{chunk-Q67VT5XL.js → chunk-DESSPQBS.js} +59 -10
  24. package/dist/{chunk-W7EBL7ZU.js → chunk-DP4Q2HMO.js} +2 -2
  25. package/dist/{chunk-5EXHNXPL.js → chunk-DPJ4T2LQ.js} +2 -2
  26. package/dist/{chunk-BQLQSWKZ.js → chunk-EN6XTVLZ.js} +2 -2
  27. package/dist/{chunk-TORDOOJ5.js → chunk-EYRZ6ZUB.js} +1 -1
  28. package/dist/{chunk-NI4FHG2K.js → chunk-EZTBWWMS.js} +2 -2
  29. package/dist/{chunk-UQM3G5A2.js → chunk-FWCM2TKJ.js} +2 -2
  30. package/dist/{chunk-OSAWNZVM.js → chunk-GCTONBF6.js} +1 -1
  31. package/dist/{chunk-2ZNJWIQG.js → chunk-HPUXHSKR.js} +2 -2
  32. package/dist/{chunk-ZPZ7XDA6.js → chunk-HTZTBXKL.js} +2 -2
  33. package/dist/{chunk-MCKP4F72.js → chunk-I7JMGCV6.js} +26 -5
  34. package/dist/{chunk-OGJCRNGE.js → chunk-IA23CLGV.js} +2 -2
  35. package/dist/{chunk-YEFKQYKA.js → chunk-IKGUBSZP.js} +2 -2
  36. package/dist/{chunk-XMSKJ5PV.js → chunk-IKI5FBNO.js} +2 -2
  37. package/dist/{chunk-OCMSAKWV.js → chunk-JA56EQJO.js} +15 -3
  38. package/dist/{chunk-TCTZW4A6.js → chunk-JLUFPUIL.js} +2 -2
  39. package/dist/{chunk-WEPK7SZF.js → chunk-KTPSQJ5L.js} +2 -2
  40. package/dist/{chunk-T5AZAOG5.js → chunk-LK5ZIAIE.js} +1 -1
  41. package/dist/{chunk-XROI44ZP.js → chunk-M4KGY2PC.js} +2 -2
  42. package/dist/chunk-MEAIGK3W.js +58 -0
  43. package/dist/{chunk-QJW5LDP4.js → chunk-NSMSOIEW.js} +2 -2
  44. package/dist/{chunk-FB63TZVI.js → chunk-OF6455OV.js} +2 -2
  45. package/dist/{chunk-6OMG4I7M.js → chunk-OIWW5TG3.js} +2 -2
  46. package/dist/{chunk-6KLGA6IR.js → chunk-Q6VTTPG4.js} +2 -2
  47. package/dist/{chunk-J4ANIXIV.js → chunk-QDLWTOII.js} +2 -2
  48. package/dist/{chunk-EBNMV2VO.js → chunk-RRXJNZX5.js} +1 -1
  49. package/dist/{chunk-FVEACSKE.js → chunk-RXBLWQQI.js} +2 -2
  50. package/dist/{chunk-L7NRPLE5.js → chunk-S6JWYPVW.js} +2 -2
  51. package/dist/{chunk-JDFNMFOZ.js → chunk-SOXXBQ4P.js} +2 -2
  52. package/dist/{chunk-4EYKGTSQ.js → chunk-T45PWXNA.js} +2 -2
  53. package/dist/{chunk-MD553LDL.js → chunk-TRPXLCND.js} +2 -2
  54. package/dist/{chunk-ZMZSBJBC.js → chunk-U223J425.js} +174 -170
  55. package/dist/{chunk-ZCOFZY5M.js → chunk-UUQVNDBG.js} +2 -2
  56. package/dist/{chunk-53F4PRNC.js → chunk-W3QOEPUN.js} +2 -2
  57. package/dist/{chunk-S6U6TCMN.js → chunk-WC7EDJHC.js} +2 -2
  58. package/dist/{chunk-KQAT4XBL.js → chunk-WWQO7QKV.js} +2 -2
  59. package/dist/{chunk-BY5O6LNC.js → chunk-XJBDESCX.js} +1 -1
  60. package/dist/{chunk-ZZ6TWKGS.js → chunk-XQDXQ7WG.js} +2 -2
  61. package/dist/{chunk-MBTUO3ZL.js → chunk-YD2ZPFT7.js} +2 -2
  62. package/dist/{chunk-ZLU4Y3O2.js → chunk-YHO7GNZK.js} +2 -2
  63. package/dist/{chunk-Y3S5SRVM.js → chunk-YSD4NSCE.js} +2 -2
  64. package/dist/chunk-Z5I2T75Z.js +70 -0
  65. package/dist/{chunk-IJ44LR7N.js → chunk-ZKJXGQCR.js} +2 -2
  66. package/dist/{chunk-GU6THOAB.js → chunk-ZKMWJNDQ.js} +2 -2
  67. package/dist/{chunk-OPPHF3TF.js → chunk-ZKVRGKLM.js} +3 -3
  68. package/dist/{clone-CbmoWwu4.d.ts → clone-DNcpkYAA.d.ts} +2 -2
  69. package/dist/comment-IAZJHG6G.js +10 -0
  70. package/dist/{crm-L5RYAAF3.js → crm-AFJSSPHK.js} +5 -5
  71. package/dist/dashboard-2DLFZM2J.js +10 -0
  72. package/dist/database/index.d.ts +3 -3
  73. package/dist/database/index.js +11 -11
  74. package/dist/database-5M7ZA33U.js +10 -0
  75. package/dist/database-field-IFUWOK7X.js +10 -0
  76. package/dist/database-row-C52KCOPB.js +10 -0
  77. package/dist/database-select-option-AEAPKXEE.js +10 -0
  78. package/dist/database-view-GUGJHS7J.js +10 -0
  79. package/dist/debug-report-BTNZAKX3.js +10 -0
  80. package/dist/draft-KGHITKX2.js +10 -0
  81. package/dist/experiment-JXHENWXV.js +10 -0
  82. package/dist/{external-item-P2E5X7BZ.js → external-item-ZVD33IXV.js} +5 -5
  83. package/dist/external-reference-LGFNVEKC.js +8 -0
  84. package/dist/feed-CLEHVA6Q.js +12 -0
  85. package/dist/feed-item-QXRIE6FU.js +12 -0
  86. package/dist/{folder-6KM3KYD5.js → folder-NU5TJFOT.js} +3 -3
  87. package/dist/{game-5AK5XWBR.js → game-7WW2JX6O.js} +5 -5
  88. package/dist/grant-W772T6FE.js +8 -0
  89. package/dist/{grant-expiration-cleaner-Bm1fSG42.d.ts → grant-expiration-cleaner-1by9wRlb.d.ts} +7 -2
  90. package/dist/import-batch-ZRU4FY6Y.js +12 -0
  91. package/dist/{inbox-state-E5NSVOGP.js → inbox-state-IO5C7HVE.js} +3 -3
  92. package/dist/index.d.ts +8 -7
  93. package/dist/index.js +175 -157
  94. package/dist/map-BZAVGCR6.js +10 -0
  95. package/dist/media-asset-VHFL65HI.js +8 -0
  96. package/dist/{meeting-LMUYTZBF.js → meeting-PVNKBGTI.js} +5 -5
  97. package/dist/{memory-PNRTMBZO.js → memory-5PD3XCKB.js} +3 -3
  98. package/dist/metric-6IGGFJMB.js +10 -0
  99. package/dist/milestone-MZAZCWGR.js +12 -0
  100. package/dist/{moderation-FFHETMRB.js → moderation-CXQB77CP.js} +3 -3
  101. package/dist/observation-O3DLKVIH.js +10 -0
  102. package/dist/page-UE5NPYEF.js +10 -0
  103. package/dist/posting-5VZZMOKS.js +12 -0
  104. package/dist/{profile-XBPZQA3C.js → profile-USKJ6PN7.js} +3 -3
  105. package/dist/project-UHGGEFLP.js +10 -0
  106. package/dist/{query-ast-Bvg0Wolx.d.ts → query-ast-NV5StnHo.d.ts} +1 -1
  107. package/dist/reaction-KD3G75UH.js +10 -0
  108. package/dist/{registry-_49rC6IG.d.ts → registry-s1fYgCSj.d.ts} +1 -1
  109. package/dist/saved-view-AZTUINZA.js +10 -0
  110. package/dist/schema/index.d.ts +173 -12
  111. package/dist/schema/index.js +96 -80
  112. package/dist/{schema-extension-LNRF2YRD.js → schema-extension-DV5D7JCQ.js} +5 -5
  113. package/dist/{space-IJU24PBH.js → space-THD2MWHR.js} +6 -6
  114. package/dist/{space-membership-DEUMM7NV.js → space-membership-M3QFMONE.js} +3 -3
  115. package/dist/store/index.d.ts +18 -5
  116. package/dist/store/index.js +4 -4
  117. package/dist/{store-DEWnip2G.d.ts → store-BIDKtpjW.d.ts} +56 -1
  118. package/dist/{system-ILHCZOVO.js → system-LFIMY3QQ.js} +3 -3
  119. package/dist/{tag-SKCHM3U5.js → tag-W7ZYPXHK.js} +3 -3
  120. package/dist/{task-7AOBP7WC.js → task-DHTPD66H.js} +5 -5
  121. package/dist/task-view-J2WRE62C.js +10 -0
  122. package/dist/transaction-ANNDXCJM.js +12 -0
  123. package/dist/transcription-DFTQ4FQ4.js +12 -0
  124. package/dist/{types-BB8-SLEa.d.ts → types-C64g-IXg.d.ts} +87 -2
  125. package/dist/user-widget-5IRVORF3.js +8 -0
  126. package/dist/workspace-RC4V4IF3.js +8 -0
  127. package/package.json +7 -7
  128. package/dist/account-MWNCH4GJ.js +0 -12
  129. package/dist/budget-NN7P35XP.js +0 -12
  130. package/dist/canvas-6WYBNH53.js +0 -10
  131. package/dist/channel-AT3LQF4A.js +0 -12
  132. package/dist/chat-message-47LETTYF.js +0 -10
  133. package/dist/comment-NIMFL4XB.js +0 -10
  134. package/dist/dashboard-JMKTTRA7.js +0 -10
  135. package/dist/database-GIXSPZJW.js +0 -10
  136. package/dist/database-field-3EPAMZUR.js +0 -10
  137. package/dist/database-row-5MEIOJ52.js +0 -10
  138. package/dist/database-select-option-BBBJFLLH.js +0 -10
  139. package/dist/database-view-DM7YCTZT.js +0 -10
  140. package/dist/experiment-DOVOZ34Y.js +0 -10
  141. package/dist/external-reference-7BSFF6SA.js +0 -8
  142. package/dist/feed-2IXHHP6O.js +0 -12
  143. package/dist/feed-item-DPE6LN7I.js +0 -12
  144. package/dist/grant-WTQSNT5A.js +0 -8
  145. package/dist/import-batch-IXBJLQPJ.js +0 -12
  146. package/dist/map-RG5Y3CPC.js +0 -10
  147. package/dist/media-asset-QTCGLIZA.js +0 -8
  148. package/dist/metric-65SVOX5C.js +0 -10
  149. package/dist/milestone-XEO6ZGDG.js +0 -12
  150. package/dist/observation-2Y3QKUXM.js +0 -10
  151. package/dist/page-2V27JGKJ.js +0 -10
  152. package/dist/posting-GBOSZCMZ.js +0 -12
  153. package/dist/project-CQL5LN26.js +0 -10
  154. package/dist/reaction-T2DTJBBV.js +0 -10
  155. package/dist/saved-view-4R2DBCL3.js +0 -10
  156. package/dist/task-view-NUGKELJP.js +0 -10
  157. package/dist/transaction-ZDSEGDIR.js +0 -12
  158. package/dist/transcription-PSCLDAGX.js +0 -12
  159. package/dist/user-widget-RLY2N46A.js +0 -8
  160. package/dist/workspace-WDKSQMOK.js +0 -8
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  defineSchema,
6
6
  json,
@@ -8,7 +8,7 @@ import {
8
8
  relation,
9
9
  select,
10
10
  text
11
- } from "./chunk-EBNMV2VO.js";
11
+ } from "./chunk-RRXJNZX5.js";
12
12
 
13
13
  // src/schema/schemas/metric.ts
14
14
  var MetricSchema = defineSchema({
@@ -3,10 +3,10 @@ import {
3
3
  select,
4
4
  text,
5
5
  url
6
- } from "./chunk-EBNMV2VO.js";
6
+ } from "./chunk-RRXJNZX5.js";
7
7
  import {
8
8
  presets
9
- } from "./chunk-RL64OJJ5.js";
9
+ } from "./chunk-D4LUUZYD.js";
10
10
 
11
11
  // src/schema/schemas/external-reference.ts
12
12
  var ExternalReferenceSchema = defineSchema({
@@ -1,6 +1,6 @@
1
1
  import {
2
- spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
2
+ spaceContributorAuthorization
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  checkbox,
6
6
  created,
@@ -11,7 +11,7 @@ import {
11
11
  json,
12
12
  relation,
13
13
  text
14
- } from "./chunk-EBNMV2VO.js";
14
+ } from "./chunk-RRXJNZX5.js";
15
15
 
16
16
  // src/schema/schemas/chat-message.ts
17
17
  var ChatMessageSchema = defineSchema({
@@ -44,8 +44,9 @@ var ChatMessageSchema = defineSchema({
44
44
  createdBy: createdBy()
45
45
  },
46
46
  document: void 0,
47
- // Inherits access from its home Space (exploration 0181/0192).
48
- authorization: spaceCascadeAuthorization("channel")
47
+ // Inherits access from its home Space (exploration 0181/0192); members may
48
+ // post but only the author (or space admins) may edit a message (0304).
49
+ authorization: spaceContributorAuthorization("channel")
49
50
  });
50
51
 
51
52
  export {
@@ -0,0 +1,41 @@
1
+ import {
2
+ spaceContributorAuthorization
3
+ } from "./chunk-JA56EQJO.js";
4
+ import {
5
+ created,
6
+ createdBy,
7
+ defineSchema,
8
+ json,
9
+ relation,
10
+ text
11
+ } from "./chunk-RRXJNZX5.js";
12
+
13
+ // src/schema/schemas/checkpoint.ts
14
+ var CHECKPOINT_SCHEMA_IRI = "xnet://xnet.fyi/Checkpoint@1.0.0";
15
+ var CheckpointSchema = defineSchema({
16
+ name: "Checkpoint",
17
+ namespace: "xnet://xnet.fyi/",
18
+ properties: {
19
+ /** User-given version name ("Draft sent to review", "Before the rewrite") */
20
+ name: text({ required: true, maxLength: 200 }),
21
+ /** Optional longer note shown in the Time Machine */
22
+ note: text({ maxLength: 2e3 }),
23
+ /** Per-node frontier: nodeId -> { hash, yjsSnapshotRef? } */
24
+ frontier: json({}),
25
+ /** The scope this checkpoint was taken over (page, database, space, …) */
26
+ scope: relation({}),
27
+ /** Space containment (single-valued) — drives the authorization roles */
28
+ space: relation({ target: "xnet://xnet.fyi/Space@1.0.0" }),
29
+ createdAt: created(),
30
+ createdBy: createdBy()
31
+ },
32
+ document: void 0,
33
+ // Checkpoints of shared content are visible to the space that content
34
+ // lives in; contributors can create their own.
35
+ authorization: spaceContributorAuthorization()
36
+ });
37
+
38
+ export {
39
+ CHECKPOINT_SCHEMA_IRI,
40
+ CheckpointSchema
41
+ };
@@ -4,10 +4,10 @@ import {
4
4
  number,
5
5
  select,
6
6
  text
7
- } from "./chunk-EBNMV2VO.js";
7
+ } from "./chunk-RRXJNZX5.js";
8
8
  import {
9
9
  presets
10
- } from "./chunk-RL64OJJ5.js";
10
+ } from "./chunk-D4LUUZYD.js";
11
11
 
12
12
  // src/schema/schemas/media-asset.ts
13
13
  var MediaAssetSchema = defineSchema({
@@ -7,10 +7,10 @@ import {
7
7
  defineSchema,
8
8
  relation,
9
9
  text
10
- } from "./chunk-EBNMV2VO.js";
10
+ } from "./chunk-RRXJNZX5.js";
11
11
  import {
12
12
  presets
13
- } from "./chunk-RL64OJJ5.js";
13
+ } from "./chunk-D4LUUZYD.js";
14
14
 
15
15
  // src/schema/schemas/folder.ts
16
16
  var FOLDER_SCHEMA_IRI = "xnet://xnet.fyi/Folder@1.0.0";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  created,
6
6
  createdBy,
@@ -11,7 +11,7 @@ import {
11
11
  select,
12
12
  text,
13
13
  url
14
- } from "./chunk-EBNMV2VO.js";
14
+ } from "./chunk-RRXJNZX5.js";
15
15
 
16
16
  // src/schema/schemas/external-item.ts
17
17
  var EXTERNAL_ITEM_SCHEMA_IRI = "xnet://xnet.fyi/ExternalItem@1.0.0";
@@ -219,7 +219,7 @@ function validateAuthorization(auth, properties) {
219
219
  }
220
220
  }
221
221
  }
222
- const mutationActions = ["write", "delete", "share"];
222
+ const mutationActions = ["create", "update", "write", "delete", "share"];
223
223
  for (const actionName of mutationActions) {
224
224
  const expr = auth.actions[actionName];
225
225
  if (expr && hasPublicAccess(expr)) {
@@ -230,6 +230,16 @@ function validateAuthorization(auth, properties) {
230
230
  });
231
231
  }
232
232
  }
233
+ const hasCreate = Boolean(auth.actions.create);
234
+ const hasUpdate = Boolean(auth.actions.update);
235
+ if (hasCreate !== hasUpdate && !auth.actions.write) {
236
+ const missing = hasCreate ? "update" : "create";
237
+ errors.push({
238
+ code: "AUTH_SCHEMA_INCOMPLETE_MUTATION_ACTIONS",
239
+ message: `Action '${missing}' has no expression and no 'write' fallback \u2014 define '${missing}' or add a 'write' action`,
240
+ path: `authorization.actions.${missing}`
241
+ });
242
+ }
233
243
  return { valid: errors.length === 0, errors };
234
244
  }
235
245
 
@@ -576,6 +586,8 @@ function warnLegacySchema(schema) {
576
586
  // src/auth/hub-policy.ts
577
587
  var SCHEMA_ACTION_TO_HUB = {
578
588
  read: "read",
589
+ create: "write",
590
+ update: "write",
579
591
  write: "write",
580
592
  share: "share",
581
593
  delete: "admin"
@@ -635,7 +647,7 @@ async function computeRecipients(schema, node, dependencies) {
635
647
  const grants = dependencies.grantIndex?.findGrantsForResource(node.id) ?? [];
636
648
  for (const grant of grants) {
637
649
  const actions = parseGrantActions(grant.properties.actions);
638
- if (actions.includes("read") || actions.includes("write")) {
650
+ if (actions.includes("read") || actions.includes("write") || actions.includes("update")) {
639
651
  const grantee = grant.properties.grantee;
640
652
  if (typeof grantee === "string" && grantee.startsWith("did:key:")) {
641
653
  recipients.add(grantee);
@@ -807,6 +819,12 @@ async function handleAuthMigration(oldSchema, newSchema, node, dependencies) {
807
819
  await dependencies.rotateContentKeyForNode(node.id, newRecipients);
808
820
  }
809
821
 
822
+ // src/auth/evaluator.ts
823
+ import {
824
+ actionExpressionOrder,
825
+ grantActionSatisfies
826
+ } from "@xnetjs/core";
827
+
810
828
  // src/auth/grants.ts
811
829
  var GRANT_SCHEMA_IRI = "xnet://xnet.fyi/Grant";
812
830
  function isGrantActive(grant, now = Date.now()) {
@@ -1303,7 +1321,7 @@ var DefaultPolicyEvaluator = class {
1303
1321
  this.emitDecision(decision2);
1304
1322
  return decision2;
1305
1323
  }
1306
- const useCache = !input.patch;
1324
+ const useCache = !input.patch && !input.node;
1307
1325
  const cached = useCache ? this.cache.get(input.subject, input.action, input.nodeId) : void 0;
1308
1326
  if (cached) {
1309
1327
  const decision2 = {
@@ -1356,7 +1374,7 @@ var DefaultPolicyEvaluator = class {
1356
1374
  this.emitDecision(decision2);
1357
1375
  return decision2;
1358
1376
  }
1359
- const actionExpr = auth.actions[input.action];
1377
+ const actionExpr = resolveActionExpression(auth.actions, input.action);
1360
1378
  if (!actionExpr) {
1361
1379
  const decision2 = this.deny(input, ["DENY_NO_ROLE_MATCH"], start, [...roles]);
1362
1380
  this.emitDecision(decision2);
@@ -1414,7 +1432,7 @@ var DefaultPolicyEvaluator = class {
1414
1432
  duration: performance.now() - roleStart
1415
1433
  });
1416
1434
  const auth = deserializeAuthorization(schema.schema.authorization);
1417
- actionExpr = auth.actions[input.action];
1435
+ actionExpr = resolveActionExpression(auth.actions, input.action);
1418
1436
  const evalStart = performance.now();
1419
1437
  const requiredRoles = actionExpr ? extractRoleRefs(actionExpr) : [];
1420
1438
  const allowed = actionExpr ? evaluateExpression(actionExpr, roles, true) : false;
@@ -1488,14 +1506,15 @@ var DefaultPolicyEvaluator = class {
1488
1506
  continue;
1489
1507
  }
1490
1508
  const actions = parseActions(grant.properties.actions);
1491
- if (actions.includes(input.action)) {
1509
+ if (actions.some((granted) => grantActionSatisfies(granted, input.action))) {
1492
1510
  return grant;
1493
1511
  }
1494
1512
  }
1495
1513
  return null;
1496
1514
  }
1497
1515
  checkFieldRules(input, fieldRules, roles) {
1498
- if (input.action !== "write" || !input.patch || !fieldRules) {
1516
+ const isMutation = input.action === "write" || input.action === "update" || input.action === "create";
1517
+ if (!isMutation || !input.patch || !fieldRules) {
1499
1518
  return false;
1500
1519
  }
1501
1520
  for (const fieldName of Object.keys(input.patch)) {
@@ -1617,6 +1636,13 @@ function membershipRoleAtLeast(edgeRole, resolver) {
1617
1636
  function isDid2(value) {
1618
1637
  return typeof value === "string" && value.startsWith("did:key:");
1619
1638
  }
1639
+ function resolveActionExpression(actions, action) {
1640
+ for (const candidate of actionExpressionOrder(action)) {
1641
+ const expr = actions[candidate];
1642
+ if (expr) return expr;
1643
+ }
1644
+ return void 0;
1645
+ }
1620
1646
  function parseActions(value) {
1621
1647
  if (Array.isArray(value)) {
1622
1648
  return value.filter((entry) => typeof entry === "string");
@@ -1770,7 +1796,8 @@ var StoreAuth = class {
1770
1796
  subject: this.options.actorDid,
1771
1797
  action: input.action,
1772
1798
  nodeId: input.nodeId,
1773
- patch: input.patch
1799
+ patch: input.patch,
1800
+ node: input.node ? { ...input.node, createdBy: input.node.createdBy ?? this.options.actorDid } : void 0
1774
1801
  });
1775
1802
  }
1776
1803
  async explain(input) {
@@ -2107,7 +2134,7 @@ function parseActions2(value) {
2107
2134
  }
2108
2135
  }
2109
2136
  function isAuthAction(value) {
2110
- return value === "read" || value === "write" || value === "delete" || value === "share" || value === "admin";
2137
+ return value === "read" || value === "create" || value === "update" || value === "write" || value === "delete" || value === "share" || value === "admin";
2111
2138
  }
2112
2139
  function parseDid(value) {
2113
2140
  if (typeof value === "string" && value.startsWith("did:key:")) {
@@ -1,3 +1,6 @@
1
+ import {
2
+ createNodeQueryDescriptor
3
+ } from "./chunk-S5RP5RKY.js";
1
4
  import {
2
5
  extKey
3
6
  } from "./chunk-PMUQACPY.js";
@@ -5,7 +8,7 @@ import {
5
8
  ExtensionFieldSchema,
6
9
  SchemaExtensionSchema,
7
10
  schemaExtensionId
8
- } from "./chunk-WEPK7SZF.js";
11
+ } from "./chunk-KTPSQJ5L.js";
9
12
  import {
10
13
  MAX_KEY_LENGTH,
11
14
  compareSortKeys,
@@ -16,19 +19,16 @@ import {
16
19
  } from "./chunk-QWFTRZQT.js";
17
20
  import {
18
21
  DatabaseRowSchema
19
- } from "./chunk-FB63TZVI.js";
22
+ } from "./chunk-OF6455OV.js";
20
23
  import {
21
24
  DatabaseFieldSchema
22
- } from "./chunk-KQAT4XBL.js";
25
+ } from "./chunk-WWQO7QKV.js";
23
26
  import {
24
27
  DatabaseSelectOptionSchema
25
- } from "./chunk-6OMG4I7M.js";
28
+ } from "./chunk-OIWW5TG3.js";
26
29
  import {
27
30
  DatabaseViewSchema
28
- } from "./chunk-MD553LDL.js";
29
- import {
30
- createNodeQueryDescriptor
31
- } from "./chunk-S5RP5RKY.js";
31
+ } from "./chunk-TRPXLCND.js";
32
32
 
33
33
  // src/database/cell-types.ts
34
34
  var CELL_PREFIX = "cell_";
@@ -264,6 +264,30 @@ function getRichTextPlainText(doc, columnId) {
264
264
  const fragment = doc.getXmlFragment(`${RICHTEXT_PREFIX}${columnId}`);
265
265
  return extractPlainText(fragment);
266
266
  }
267
+ var BLOCK_ELEMENT_NAMES = /* @__PURE__ */ new Set([
268
+ // HTML-ish / legacy names
269
+ "p",
270
+ "h1",
271
+ "h2",
272
+ "h3",
273
+ "h4",
274
+ "h5",
275
+ "h6",
276
+ "li",
277
+ "blockquote",
278
+ // TipTap / BlockNote shared names
279
+ "paragraph",
280
+ "heading",
281
+ "codeBlock",
282
+ "listItem",
283
+ "taskItem",
284
+ // BlockNote (v4) block-content names
285
+ "bulletListItem",
286
+ "numberedListItem",
287
+ "checkListItem",
288
+ "toggleListItem",
289
+ "quote"
290
+ ]);
267
291
  function extractPlainText(fragment) {
268
292
  const parts = [];
269
293
  for (let i = 0; i < fragment.length; i++) {
@@ -276,7 +300,33 @@ function extractPlainText(fragment) {
276
300
  }
277
301
  return parts.join("");
278
302
  }
303
+ function inlineAtomText(element) {
304
+ const attr = (key) => {
305
+ const value = element.getAttribute(key);
306
+ return typeof value === "string" ? value : "";
307
+ };
308
+ switch (element.nodeName) {
309
+ case "mention": {
310
+ const label = attr("label") || attr("id");
311
+ return label ? `@${label}` : "";
312
+ }
313
+ case "hashtag": {
314
+ const name = attr("name");
315
+ return name ? `#${name}` : "";
316
+ }
317
+ case "wikilink":
318
+ return element.length === 0 ? attr("title") : null;
319
+ case "inlineMath":
320
+ return attr("latex");
321
+ default:
322
+ return null;
323
+ }
324
+ }
279
325
  function extractPlainTextFromElement(element) {
326
+ const atomText = inlineAtomText(element);
327
+ if (atomText !== null) {
328
+ return atomText;
329
+ }
280
330
  const parts = [];
281
331
  for (let i = 0; i < element.length; i++) {
282
332
  const item = element.get(i);
@@ -286,8 +336,7 @@ function extractPlainTextFromElement(element) {
286
336
  parts.push(extractPlainTextFromElement(item));
287
337
  }
288
338
  }
289
- const blockElements = ["p", "h1", "h2", "h3", "h4", "h5", "h6", "li", "blockquote"];
290
- if (blockElements.includes(element.nodeName)) {
339
+ if (BLOCK_ELEMENT_NAMES.has(element.nodeName)) {
291
340
  parts.push("\n");
292
341
  }
293
342
  return parts.join("");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  date,
6
6
  defineSchema,
@@ -9,7 +9,7 @@ import {
9
9
  relation,
10
10
  select,
11
11
  text
12
- } from "./chunk-EBNMV2VO.js";
12
+ } from "./chunk-RRXJNZX5.js";
13
13
 
14
14
  // src/schema/schemas/observation.ts
15
15
  var ObservationSchema = defineSchema({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  created,
6
6
  createdBy,
@@ -9,7 +9,7 @@ import {
9
9
  relation,
10
10
  text,
11
11
  url
12
- } from "./chunk-EBNMV2VO.js";
12
+ } from "./chunk-RRXJNZX5.js";
13
13
 
14
14
  // src/schema/schemas/feed-item.ts
15
15
  var FEED_ITEM_SCHEMA_IRI = "xnet://xnet.fyi/FeedItem@1.0.0";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  date,
6
6
  defineSchema,
@@ -11,7 +11,7 @@ import {
11
11
  relation,
12
12
  select,
13
13
  text
14
- } from "./chunk-EBNMV2VO.js";
14
+ } from "./chunk-RRXJNZX5.js";
15
15
 
16
16
  // src/schema/schemas/game.ts
17
17
  var GAME_NAMESPACE = "xnet://xnet.fyi/";
@@ -4,7 +4,7 @@ import {
4
4
  defineSchema,
5
5
  person,
6
6
  text
7
- } from "./chunk-EBNMV2VO.js";
7
+ } from "./chunk-RRXJNZX5.js";
8
8
 
9
9
  // src/schema/schemas/profile.ts
10
10
  var ProfileSchema = defineSchema({
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  defineSchema,
6
6
  json,
7
7
  relation,
8
8
  select,
9
9
  text
10
- } from "./chunk-EBNMV2VO.js";
10
+ } from "./chunk-RRXJNZX5.js";
11
11
 
12
12
  // src/schema/schemas/map.ts
13
13
  var MapSchema = defineSchema({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  checkbox,
6
6
  date,
@@ -9,7 +9,7 @@ import {
9
9
  relation,
10
10
  select,
11
11
  text
12
- } from "./chunk-EBNMV2VO.js";
12
+ } from "./chunk-RRXJNZX5.js";
13
13
 
14
14
  // src/schema/schemas/task.ts
15
15
  var TaskSchema = defineSchema({
@@ -3,7 +3,7 @@ import {
3
3
  number,
4
4
  person,
5
5
  text
6
- } from "./chunk-EBNMV2VO.js";
6
+ } from "./chunk-RRXJNZX5.js";
7
7
 
8
8
  // src/schema/schemas/grant.ts
9
9
  var GrantSchema = defineSchema({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  defineSchema,
6
6
  file,
@@ -8,7 +8,7 @@ import {
8
8
  relation,
9
9
  select,
10
10
  text
11
- } from "./chunk-EBNMV2VO.js";
11
+ } from "./chunk-RRXJNZX5.js";
12
12
 
13
13
  // src/schema/schemas/transcription.ts
14
14
  var TRANSCRIPTION_SCHEMA_IRI = "xnet://xnet.fyi/Transcription@1.0.0";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  defineSchema,
6
6
  money,
7
7
  relation,
8
8
  select,
9
9
  text
10
- } from "./chunk-EBNMV2VO.js";
10
+ } from "./chunk-RRXJNZX5.js";
11
11
 
12
12
  // src/schema/schemas/budget.ts
13
13
  var BUDGET_SCHEMA_IRI = "xnet://xnet.fyi/Budget@1.0.0";
@@ -1,6 +1,6 @@
1
1
  import {
2
- spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
2
+ spaceContributorAuthorization
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  checkbox,
6
6
  created,
@@ -13,7 +13,11 @@ import {
13
13
  relation,
14
14
  select,
15
15
  text
16
- } from "./chunk-EBNMV2VO.js";
16
+ } from "./chunk-RRXJNZX5.js";
17
+ import {
18
+ allow,
19
+ role
20
+ } from "./chunk-D4LUUZYD.js";
17
21
 
18
22
  // src/schema/schemas/comment.ts
19
23
  var CommentSchema = defineSchema({
@@ -83,9 +87,26 @@ var CommentSchema = defineSchema({
83
87
  },
84
88
  // Comments are plain text + markdown, no collaborative Y.Doc needed
85
89
  document: void 0,
86
- // Inherits access from its home Space (exploration 0181/0192).
87
- authorization: spaceCascadeAuthorization("target")
90
+ // Inherits access from the target's Space (exploration 0181/0192), with
91
+ // author-owned mutation semantics (0304): space folk down to the commenter
92
+ // rung — plus the target's own author — may add comments, but only the
93
+ // comment's author (or space admins) may edit one afterwards.
94
+ authorization: commentAuthorization()
88
95
  });
96
+ function commentAuthorization() {
97
+ const contributor = spaceContributorAuthorization("target");
98
+ return {
99
+ ...contributor,
100
+ roles: {
101
+ ...contributor.roles,
102
+ targetOwner: role.relation("target", "owner")
103
+ },
104
+ actions: {
105
+ ...contributor.actions,
106
+ create: allow("targetOwner", "spaceCommenter", "spaceMember", "spaceAdmin", "spaceOwner")
107
+ }
108
+ };
109
+ }
89
110
 
90
111
  export {
91
112
  CommentSchema
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  date,
6
6
  defineSchema,
7
7
  relation,
8
8
  select,
9
9
  text
10
- } from "./chunk-EBNMV2VO.js";
10
+ } from "./chunk-RRXJNZX5.js";
11
11
 
12
12
  // src/schema/schemas/milestone.ts
13
13
  var MILESTONE_SCHEMA_IRI = "xnet://xnet.fyi/Milestone@1.0.0";
@@ -4,10 +4,10 @@ import {
4
4
  defineSchema,
5
5
  json,
6
6
  person
7
- } from "./chunk-EBNMV2VO.js";
7
+ } from "./chunk-RRXJNZX5.js";
8
8
  import {
9
9
  presets
10
- } from "./chunk-RL64OJJ5.js";
10
+ } from "./chunk-D4LUUZYD.js";
11
11
 
12
12
  // src/schema/schemas/inbox-state.ts
13
13
  var DEFAULT_CHANNEL_TIER = "mentions";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  spaceCascadeAuthorization
3
- } from "./chunk-OCMSAKWV.js";
3
+ } from "./chunk-JA56EQJO.js";
4
4
  import {
5
5
  checkbox,
6
6
  defineSchema,
7
7
  relation,
8
8
  select,
9
9
  text
10
- } from "./chunk-EBNMV2VO.js";
10
+ } from "./chunk-RRXJNZX5.js";
11
11
 
12
12
  // src/schema/schemas/account.ts
13
13
  var ACCOUNT_SCHEMA_IRI = "xnet://xnet.fyi/Account@1.0.0";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  SPACE_MEMBERSHIP_SCHEMA_IRI
3
- } from "./chunk-T5AZAOG5.js";
3
+ } from "./chunk-LK5ZIAIE.js";
4
4
  import {
5
5
  allow,
6
6
  role
7
- } from "./chunk-RL64OJJ5.js";
7
+ } from "./chunk-D4LUUZYD.js";
8
8
 
9
9
  // src/schema/schemas/space-authorization.ts
10
10
  var ROLE_ORDER = ["viewer", "commenter", "member", "admin", "owner"];
@@ -71,8 +71,20 @@ function spaceCascadeAuthorization(relationName = "space") {
71
71
  }
72
72
  };
73
73
  }
74
+ function spaceContributorAuthorization(relationName = "space") {
75
+ const cascade = spaceCascadeAuthorization(relationName);
76
+ return {
77
+ ...cascade,
78
+ actions: {
79
+ ...cascade.actions,
80
+ create: allow("spaceOwner", "spaceAdmin", "spaceMember"),
81
+ update: allow("owner", "spaceOwner", "spaceAdmin")
82
+ }
83
+ };
84
+ }
74
85
 
75
86
  export {
76
87
  spaceOwnAuthorization,
77
- spaceCascadeAuthorization
88
+ spaceCascadeAuthorization,
89
+ spaceContributorAuthorization
78
90
  };