@powerhousedao/reactor-api 6.0.0-dev.1 → 6.0.0-dev.100

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 (273) hide show
  1. package/dist/codegen.js +1 -1
  2. package/dist/codegen.js.map +1 -1
  3. package/dist/index.d.ts +4 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +4 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/config.d.ts +1 -2
  8. package/dist/src/config.d.ts.map +1 -1
  9. package/dist/src/config.js +1 -5
  10. package/dist/src/config.js.map +1 -1
  11. package/dist/src/graphql/auth/resolvers.d.ts +17 -0
  12. package/dist/src/graphql/auth/resolvers.d.ts.map +1 -1
  13. package/dist/src/graphql/auth/resolvers.js +54 -0
  14. package/dist/src/graphql/auth/resolvers.js.map +1 -1
  15. package/dist/src/graphql/auth/schema.graphql +27 -5
  16. package/dist/src/graphql/auth/subgraph.d.ts +25 -0
  17. package/dist/src/graphql/auth/subgraph.d.ts.map +1 -1
  18. package/dist/src/graphql/auth/subgraph.js +45 -1
  19. package/dist/src/graphql/auth/subgraph.js.map +1 -1
  20. package/dist/src/graphql/base-subgraph.d.ts +12 -4
  21. package/dist/src/graphql/base-subgraph.d.ts.map +1 -1
  22. package/dist/src/graphql/base-subgraph.js +94 -2
  23. package/dist/src/graphql/base-subgraph.js.map +1 -1
  24. package/dist/src/graphql/document-model-subgraph.d.ts +16 -44
  25. package/dist/src/graphql/document-model-subgraph.d.ts.map +1 -1
  26. package/dist/src/graphql/document-model-subgraph.js +300 -88
  27. package/dist/src/graphql/document-model-subgraph.js.map +1 -1
  28. package/dist/src/graphql/graphql-manager.d.ts +28 -6
  29. package/dist/src/graphql/graphql-manager.d.ts.map +1 -1
  30. package/dist/src/graphql/graphql-manager.js +269 -161
  31. package/dist/src/graphql/graphql-manager.js.map +1 -1
  32. package/dist/src/graphql/index.d.ts +2 -1
  33. package/dist/src/graphql/index.d.ts.map +1 -1
  34. package/dist/src/graphql/index.js +2 -1
  35. package/dist/src/graphql/index.js.map +1 -1
  36. package/dist/src/graphql/packages/index.d.ts +2 -0
  37. package/dist/src/graphql/packages/index.d.ts.map +1 -0
  38. package/dist/src/graphql/packages/index.js +2 -0
  39. package/dist/src/graphql/packages/index.js.map +1 -0
  40. package/dist/src/graphql/packages/resolvers.d.ts +31 -0
  41. package/dist/src/graphql/packages/resolvers.d.ts.map +1 -0
  42. package/dist/src/graphql/packages/resolvers.js +37 -0
  43. package/dist/src/graphql/packages/resolvers.js.map +1 -0
  44. package/dist/src/graphql/packages/schema.graphql +50 -0
  45. package/dist/src/graphql/packages/subgraph.d.ts +55 -0
  46. package/dist/src/graphql/packages/subgraph.d.ts.map +1 -0
  47. package/dist/src/graphql/packages/subgraph.js +73 -0
  48. package/dist/src/graphql/packages/subgraph.js.map +1 -0
  49. package/dist/src/graphql/reactor/adapters.d.ts +13 -5
  50. package/dist/src/graphql/reactor/adapters.d.ts.map +1 -1
  51. package/dist/src/graphql/reactor/adapters.js +38 -40
  52. package/dist/src/graphql/reactor/adapters.js.map +1 -1
  53. package/dist/src/graphql/reactor/factory.d.ts +22 -1
  54. package/dist/src/graphql/reactor/factory.d.ts.map +1 -1
  55. package/dist/src/graphql/reactor/factory.js +1 -1
  56. package/dist/src/graphql/reactor/factory.js.map +1 -1
  57. package/dist/src/graphql/reactor/gen/graphql.d.ts +355 -76
  58. package/dist/src/graphql/reactor/gen/graphql.d.ts.map +1 -1
  59. package/dist/src/graphql/reactor/gen/graphql.js +245 -10
  60. package/dist/src/graphql/reactor/gen/graphql.js.map +1 -1
  61. package/dist/src/graphql/reactor/index.d.ts +1 -1
  62. package/dist/src/graphql/reactor/index.d.ts.map +1 -1
  63. package/dist/src/graphql/reactor/index.js +1 -1
  64. package/dist/src/graphql/reactor/index.js.map +1 -1
  65. package/dist/src/graphql/reactor/operations.graphql +191 -1
  66. package/dist/src/graphql/reactor/requester.with-zod.d.ts.map +1 -1
  67. package/dist/src/graphql/reactor/requester.with-zod.js +114 -38
  68. package/dist/src/graphql/reactor/requester.with-zod.js.map +1 -1
  69. package/dist/src/graphql/reactor/resolvers.d.ts +90 -26
  70. package/dist/src/graphql/reactor/resolvers.d.ts.map +1 -1
  71. package/dist/src/graphql/reactor/resolvers.js +277 -77
  72. package/dist/src/graphql/reactor/resolvers.js.map +1 -1
  73. package/dist/src/graphql/reactor/schema.graphql +76 -30
  74. package/dist/src/graphql/reactor/subgraph.d.ts +2 -31
  75. package/dist/src/graphql/reactor/subgraph.d.ts.map +1 -1
  76. package/dist/src/graphql/reactor/subgraph.js +170 -247
  77. package/dist/src/graphql/reactor/subgraph.js.map +1 -1
  78. package/dist/src/graphql/reactor/validation.d.ts +266 -20
  79. package/dist/src/graphql/reactor/validation.d.ts.map +1 -1
  80. package/dist/src/graphql/reactor/validation.js +98 -4
  81. package/dist/src/graphql/reactor/validation.js.map +1 -1
  82. package/dist/src/graphql/system/index.d.ts +0 -1
  83. package/dist/src/graphql/system/index.d.ts.map +1 -1
  84. package/dist/src/graphql/system/index.js +0 -1
  85. package/dist/src/graphql/system/index.js.map +1 -1
  86. package/dist/src/graphql/types.d.ts +6 -8
  87. package/dist/src/graphql/types.d.ts.map +1 -1
  88. package/dist/src/graphql/utils.d.ts +1 -18
  89. package/dist/src/graphql/utils.d.ts.map +1 -1
  90. package/dist/src/graphql/utils.js +7 -35
  91. package/dist/src/graphql/utils.js.map +1 -1
  92. package/dist/src/migrations/002_add_document_protection.d.ts +4 -0
  93. package/dist/src/migrations/002_add_document_protection.d.ts.map +1 -0
  94. package/dist/src/migrations/002_add_document_protection.js +18 -0
  95. package/dist/src/migrations/002_add_document_protection.js.map +1 -0
  96. package/dist/src/migrations/index.d.ts.map +1 -1
  97. package/dist/src/migrations/index.js +2 -0
  98. package/dist/src/migrations/index.js.map +1 -1
  99. package/dist/src/packages/http-loader.d.ts +68 -0
  100. package/dist/src/packages/http-loader.d.ts.map +1 -0
  101. package/dist/src/packages/http-loader.js +176 -0
  102. package/dist/src/packages/http-loader.js.map +1 -0
  103. package/dist/src/packages/https-hooks.d.mts +23 -0
  104. package/dist/src/packages/https-hooks.d.mts.map +1 -0
  105. package/dist/src/packages/https-hooks.mjs +59 -0
  106. package/dist/src/packages/https-hooks.mjs.map +1 -0
  107. package/dist/src/packages/import-loader.d.ts +5 -3
  108. package/dist/src/packages/import-loader.d.ts.map +1 -1
  109. package/dist/src/packages/import-loader.js +19 -10
  110. package/dist/src/packages/import-loader.js.map +1 -1
  111. package/dist/src/packages/package-manager.d.ts +2 -2
  112. package/dist/src/packages/package-manager.d.ts.map +1 -1
  113. package/dist/src/packages/package-manager.js.map +1 -1
  114. package/dist/src/packages/types.d.ts +9 -4
  115. package/dist/src/packages/types.d.ts.map +1 -1
  116. package/dist/src/packages/util.d.ts +3 -2
  117. package/dist/src/packages/util.d.ts.map +1 -1
  118. package/dist/src/packages/util.js +1 -1
  119. package/dist/src/packages/util.js.map +1 -1
  120. package/dist/src/packages/vite-loader.d.ts +10 -8
  121. package/dist/src/packages/vite-loader.d.ts.map +1 -1
  122. package/dist/src/packages/vite-loader.js +33 -10
  123. package/dist/src/packages/vite-loader.js.map +1 -1
  124. package/dist/src/server.d.ts +14 -11
  125. package/dist/src/server.d.ts.map +1 -1
  126. package/dist/src/server.js +153 -92
  127. package/dist/src/server.js.map +1 -1
  128. package/dist/src/services/auth.service.d.ts +0 -12
  129. package/dist/src/services/auth.service.d.ts.map +1 -1
  130. package/dist/src/services/auth.service.js +13 -40
  131. package/dist/src/services/auth.service.js.map +1 -1
  132. package/dist/src/services/authorization.service.d.ts +70 -0
  133. package/dist/src/services/authorization.service.d.ts.map +1 -0
  134. package/dist/src/services/authorization.service.js +155 -0
  135. package/dist/src/services/authorization.service.js.map +1 -0
  136. package/dist/src/services/document-permission.service.d.ts +47 -7
  137. package/dist/src/services/document-permission.service.d.ts.map +1 -1
  138. package/dist/src/services/document-permission.service.js +162 -7
  139. package/dist/src/services/document-permission.service.js.map +1 -1
  140. package/dist/src/services/package-management.service.d.ts +32 -0
  141. package/dist/src/services/package-management.service.d.ts.map +1 -0
  142. package/dist/src/services/package-management.service.js +95 -0
  143. package/dist/src/services/package-management.service.js.map +1 -0
  144. package/dist/src/services/package-storage.d.ts +23 -0
  145. package/dist/src/services/package-storage.d.ts.map +1 -0
  146. package/dist/src/services/package-storage.js +19 -0
  147. package/dist/src/services/package-storage.js.map +1 -0
  148. package/dist/src/tracing.d.ts.map +1 -1
  149. package/dist/src/tracing.js +19 -1
  150. package/dist/src/tracing.js.map +1 -1
  151. package/dist/src/types.d.ts +5 -5
  152. package/dist/src/types.d.ts.map +1 -1
  153. package/dist/src/utils/auth.d.ts +1 -1
  154. package/dist/src/utils/auth.d.ts.map +1 -1
  155. package/dist/src/utils/auth.js +5 -12
  156. package/dist/src/utils/auth.js.map +1 -1
  157. package/dist/src/utils/create-schema.d.ts +25 -6
  158. package/dist/src/utils/create-schema.d.ts.map +1 -1
  159. package/dist/src/utils/create-schema.js +459 -23
  160. package/dist/src/utils/create-schema.js.map +1 -1
  161. package/dist/src/utils/db.d.ts +8 -0
  162. package/dist/src/utils/db.d.ts.map +1 -1
  163. package/dist/src/utils/db.js.map +1 -1
  164. package/dist/src/utils/drive-url.d.ts +2 -0
  165. package/dist/src/utils/drive-url.d.ts.map +1 -0
  166. package/dist/src/utils/drive-url.js +3 -0
  167. package/dist/src/utils/drive-url.js.map +1 -0
  168. package/dist/src/utils/index.d.ts +1 -0
  169. package/dist/src/utils/index.d.ts.map +1 -1
  170. package/dist/src/utils/index.js +1 -0
  171. package/dist/src/utils/index.js.map +1 -1
  172. package/dist/test/authorization.service.test.d.ts +2 -0
  173. package/dist/test/authorization.service.test.d.ts.map +1 -0
  174. package/dist/test/authorization.service.test.js +252 -0
  175. package/dist/test/authorization.service.test.js.map +1 -0
  176. package/dist/test/connect-switchboard-reshuffle-convergence.test.d.ts +2 -0
  177. package/dist/test/connect-switchboard-reshuffle-convergence.test.d.ts.map +1 -0
  178. package/dist/test/connect-switchboard-reshuffle-convergence.test.js +203 -0
  179. package/dist/test/connect-switchboard-reshuffle-convergence.test.js.map +1 -0
  180. package/dist/test/connect-switchboard-sync.test.d.ts +2 -0
  181. package/dist/test/connect-switchboard-sync.test.d.ts.map +1 -0
  182. package/dist/test/connect-switchboard-sync.test.js +581 -0
  183. package/dist/test/connect-switchboard-sync.test.js.map +1 -0
  184. package/dist/test/document-drive-subgraph.test.d.ts +2 -0
  185. package/dist/test/document-drive-subgraph.test.d.ts.map +1 -0
  186. package/dist/test/document-drive-subgraph.test.js +186 -0
  187. package/dist/test/document-drive-subgraph.test.js.map +1 -0
  188. package/dist/test/document-model-subgraph-permissions.test.d.ts +2 -0
  189. package/dist/test/document-model-subgraph-permissions.test.d.ts.map +1 -0
  190. package/dist/test/document-model-subgraph-permissions.test.js +563 -0
  191. package/dist/test/document-model-subgraph-permissions.test.js.map +1 -0
  192. package/dist/test/drive-info-endpoint.test.d.ts +2 -0
  193. package/dist/test/drive-info-endpoint.test.d.ts.map +1 -0
  194. package/dist/test/drive-info-endpoint.test.js +123 -0
  195. package/dist/test/drive-info-endpoint.test.js.map +1 -0
  196. package/dist/test/fault-injection-sync.test.d.ts +2 -0
  197. package/dist/test/fault-injection-sync.test.d.ts.map +1 -0
  198. package/dist/test/fault-injection-sync.test.js +196 -0
  199. package/dist/test/fault-injection-sync.test.js.map +1 -0
  200. package/dist/test/index.d.ts +0 -1
  201. package/dist/test/index.d.ts.map +1 -1
  202. package/dist/test/index.js +0 -1
  203. package/dist/test/index.js.map +1 -1
  204. package/dist/test/permissions-integration.test.js +6 -20
  205. package/dist/test/permissions-integration.test.js.map +1 -1
  206. package/dist/test/push-backfill.test.d.ts +2 -0
  207. package/dist/test/push-backfill.test.d.ts.map +1 -0
  208. package/dist/test/push-backfill.test.js +298 -0
  209. package/dist/test/push-backfill.test.js.map +1 -0
  210. package/dist/test/reactor-adapters.test.js +9 -162
  211. package/dist/test/reactor-adapters.test.js.map +1 -1
  212. package/dist/test/reactor-client.test.js +172 -13
  213. package/dist/test/reactor-client.test.js.map +1 -1
  214. package/dist/test/reactor-resolvers.test.js +8 -11
  215. package/dist/test/reactor-resolvers.test.js.map +1 -1
  216. package/dist/test/reactor-subgraph-permissions.test.js +7 -36
  217. package/dist/test/reactor-subgraph-permissions.test.js.map +1 -1
  218. package/dist/test/subscriptions.test.js +2 -0
  219. package/dist/test/subscriptions.test.js.map +1 -1
  220. package/dist/test/utils/gql-resolver-bridge.d.ts +4 -1
  221. package/dist/test/utils/gql-resolver-bridge.d.ts.map +1 -1
  222. package/dist/test/utils/gql-resolver-bridge.js +36 -7
  223. package/dist/test/utils/gql-resolver-bridge.js.map +1 -1
  224. package/dist/tsconfig.tsbuildinfo +1 -1
  225. package/package.json +46 -55
  226. package/dist/src/graphql/drive-subgraph.d.ts +0 -25
  227. package/dist/src/graphql/drive-subgraph.d.ts.map +0 -1
  228. package/dist/src/graphql/drive-subgraph.js +0 -487
  229. package/dist/src/graphql/drive-subgraph.js.map +0 -1
  230. package/dist/src/graphql/system/system-subgraph.d.ts +0 -49
  231. package/dist/src/graphql/system/system-subgraph.d.ts.map +0 -1
  232. package/dist/src/graphql/system/system-subgraph.js +0 -130
  233. package/dist/src/graphql/system/system-subgraph.js.map +0 -1
  234. package/dist/src/sync/types.d.ts +0 -10
  235. package/dist/src/sync/types.d.ts.map +0 -1
  236. package/dist/src/sync/types.js +0 -2
  237. package/dist/src/sync/types.js.map +0 -1
  238. package/dist/src/sync/utils.d.ts +0 -7
  239. package/dist/src/sync/utils.d.ts.map +0 -1
  240. package/dist/src/sync/utils.js +0 -78
  241. package/dist/src/sync/utils.js.map +0 -1
  242. package/dist/test/drive-handlers.d.ts +0 -4
  243. package/dist/test/drive-handlers.d.ts.map +0 -1
  244. package/dist/test/drive-handlers.js +0 -39
  245. package/dist/test/drive-handlers.js.map +0 -1
  246. package/dist/test/drive-subgraph-permissions.test.d.ts +0 -2
  247. package/dist/test/drive-subgraph-permissions.test.d.ts.map +0 -1
  248. package/dist/test/drive-subgraph-permissions.test.js +0 -195
  249. package/dist/test/drive-subgraph-permissions.test.js.map +0 -1
  250. package/dist/test/drive.test.d.ts +0 -2
  251. package/dist/test/drive.test.d.ts.map +0 -1
  252. package/dist/test/drive.test.js +0 -142
  253. package/dist/test/drive.test.js.map +0 -1
  254. package/dist/test/pull-responder-transmitter.test.d.ts +0 -2
  255. package/dist/test/pull-responder-transmitter.test.d.ts.map +0 -1
  256. package/dist/test/pull-responder-transmitter.test.js +0 -220
  257. package/dist/test/pull-responder-transmitter.test.js.map +0 -1
  258. package/dist/test/push-transmitter.test.d.ts +0 -2
  259. package/dist/test/push-transmitter.test.d.ts.map +0 -1
  260. package/dist/test/push-transmitter.test.js +0 -179
  261. package/dist/test/push-transmitter.test.js.map +0 -1
  262. package/dist/test/system.test.d.ts +0 -2
  263. package/dist/test/system.test.d.ts.map +0 -1
  264. package/dist/test/system.test.js +0 -211
  265. package/dist/test/system.test.js.map +0 -1
  266. package/dist/test/three-reactor-gql-sync.test.d.ts +0 -2
  267. package/dist/test/three-reactor-gql-sync.test.d.ts.map +0 -1
  268. package/dist/test/three-reactor-gql-sync.test.js +0 -368
  269. package/dist/test/three-reactor-gql-sync.test.js.map +0 -1
  270. package/dist/test/two-reactor-gql-sync.test.d.ts +0 -2
  271. package/dist/test/two-reactor-gql-sync.test.d.ts.map +0 -1
  272. package/dist/test/two-reactor-gql-sync.test.js +0 -348
  273. package/dist/test/two-reactor-gql-sync.test.js.map +0 -1
@@ -18,183 +18,119 @@ export class ReactorSubgraph extends BaseSubgraph {
18
18
  super(args);
19
19
  this.logger.verbose(`constructor()`);
20
20
  }
21
- name = "r/:reactor";
21
+ name = "r";
22
22
  hasSubscriptions = true;
23
23
  /**
24
- * Check if user has global read access (admin, user, or guest)
25
- */
26
- hasGlobalReadAccess(ctx) {
27
- const isGlobalAdmin = ctx.isAdmin?.(ctx.user?.address ?? "");
28
- const isGlobalUser = ctx.isUser?.(ctx.user?.address ?? "");
29
- const isGlobalGuest = ctx.isGuest?.(ctx.user?.address ?? "") ||
30
- process.env.FREE_ENTRY === "true";
31
- return !!(isGlobalAdmin || isGlobalUser || isGlobalGuest);
32
- }
33
- /**
34
- * Check if user has global write access (admin or user, not guest)
35
- */
36
- hasGlobalWriteAccess(ctx) {
37
- const isGlobalAdmin = ctx.isAdmin?.(ctx.user?.address ?? "");
38
- const isGlobalUser = ctx.isUser?.(ctx.user?.address ?? "");
39
- return !!(isGlobalAdmin || isGlobalUser);
40
- }
41
- /**
42
- * Get the parent IDs function for hierarchical permission checks
43
- */
44
- getParentIdsFn() {
45
- return resolvers.createGetParentIdsFn(this.reactorClient);
46
- }
47
- /**
48
- * Check if user can read a document (with hierarchy)
49
- */
50
- async canReadDocument(documentId, ctx) {
51
- // Global access allows reading
52
- if (this.hasGlobalReadAccess(ctx)) {
53
- return true;
54
- }
55
- // Check document-level permissions with hierarchy
56
- if (this.documentPermissionService) {
57
- return this.documentPermissionService.canRead(documentId, ctx.user?.address, this.getParentIdsFn());
58
- }
59
- return false;
60
- }
61
- /**
62
- * Check if user can write to a document (with hierarchy)
63
- */
64
- async canWriteDocument(documentId, ctx) {
65
- // Global write access allows writing
66
- if (this.hasGlobalWriteAccess(ctx)) {
67
- return true;
68
- }
69
- // Check document-level permissions with hierarchy
70
- if (this.documentPermissionService) {
71
- return this.documentPermissionService.canWrite(documentId, ctx.user?.address, this.getParentIdsFn());
72
- }
73
- return false;
74
- }
75
- /**
76
- * Throw an error if user cannot read the document
77
- */
78
- async assertCanRead(documentId, ctx) {
79
- const canRead = await this.canReadDocument(documentId, ctx);
80
- if (!canRead) {
81
- throw new GraphQLError("Forbidden: insufficient permissions to read this document");
82
- }
83
- }
84
- /**
85
- * Throw an error if user cannot write to the document
86
- */
87
- async assertCanWrite(documentId, ctx) {
88
- const canWrite = await this.canWriteDocument(documentId, ctx);
89
- if (!canWrite) {
90
- throw new GraphQLError("Forbidden: insufficient permissions to write to this document");
91
- }
92
- }
93
- /**
94
- * Check if user can execute specific operations on a document.
95
- * Only checks operations that have restrictions set.
96
- * Throws an error if any operation is restricted and user lacks permission.
24
+ * Check operation-level permissions for an array of actions.
25
+ * Delegates to base assertCanExecuteOperation for each action.
97
26
  */
98
27
  async assertCanExecuteOperations(documentId, actions, ctx) {
99
- // Skip if no permission service
100
- if (!this.documentPermissionService) {
101
- return;
102
- }
103
- // Global admins bypass operation-level restrictions
104
- if (ctx.isAdmin?.(ctx.user?.address ?? "")) {
105
- return;
106
- }
107
28
  for (const action of actions) {
108
- if (!action || typeof action !== "object") {
29
+ if (!action || typeof action !== "object")
109
30
  continue;
110
- }
111
31
  const actionObj = action;
112
32
  const operationType = actionObj.type;
113
- if (typeof operationType !== "string") {
33
+ if (typeof operationType !== "string")
114
34
  continue;
115
- }
116
- // Check if this operation has any restrictions set
117
- const isRestricted = await this.documentPermissionService.isOperationRestricted(documentId, operationType);
118
- if (isRestricted) {
119
- // Operation is restricted, check if user has permission
120
- const canExecute = await this.documentPermissionService.canExecuteOperation(documentId, operationType, ctx.user?.address);
121
- if (!canExecute) {
122
- throw new GraphQLError(`Forbidden: insufficient permissions to execute operation "${operationType}" on this document`);
123
- }
124
- }
35
+ await this.assertCanExecuteOperation(documentId, operationType, ctx);
125
36
  }
126
37
  }
127
38
  // Load schema from file
128
39
  typeDefs = gql(fs.readFileSync(path.join(__dirname, "schema.graphql"), "utf-8"));
129
40
  resolvers = {
41
+ // Field resolver for PHDocument.operations - fetches operations on demand
42
+ PHDocument: {
43
+ operations: async (parent, args, ctx) => {
44
+ this.logger.debug("PHDocument.operations(@parent.id, @args)", parent.id, args);
45
+ await this.assertCanRead(parent.id, ctx);
46
+ try {
47
+ // Build the filter using the document's id
48
+ const filter = {
49
+ documentId: parent.id,
50
+ branch: args.filter?.branch,
51
+ scopes: args.filter?.scopes,
52
+ actionTypes: args.filter?.actionTypes,
53
+ sinceRevision: args.filter?.sinceRevision,
54
+ timestampFrom: args.filter?.timestampFrom,
55
+ timestampTo: args.filter?.timestampTo,
56
+ };
57
+ return await resolvers.documentOperations(this.reactorClient, {
58
+ filter,
59
+ paging: args.paging,
60
+ });
61
+ }
62
+ catch (error) {
63
+ this.logger.error("Error in PHDocument.operations: @Error", error);
64
+ throw error;
65
+ }
66
+ },
67
+ },
130
68
  Query: {
131
69
  documentModels: async (_parent, args) => {
132
- this.logger.debug("documentModels", args);
70
+ this.logger.debug("documentModels(@args)", args);
133
71
  try {
134
72
  return await resolvers.documentModels(this.reactorClient, args);
135
73
  }
136
74
  catch (error) {
137
- this.logger.error("Error in documentModels:", error);
75
+ this.logger.error("Error in documentModels: @Error", error);
138
76
  throw error;
139
77
  }
140
78
  },
141
79
  document: async (_parent, args, ctx) => {
142
- this.logger.debug("document", args);
80
+ this.logger.debug("document(@args)", args);
143
81
  try {
144
- // Resolve the document ID first
145
- const doc = await resolvers.document(this.reactorClient, args);
146
- if (doc) {
147
- await this.assertCanRead(doc.document.id, ctx);
148
- }
149
- return doc;
82
+ await this.assertCanRead(args.identifier, ctx);
83
+ return await resolvers.document(this.reactorClient, args);
150
84
  }
151
85
  catch (error) {
152
- this.logger.error("Error in document:", error);
86
+ this.logger.error("Error in document: @Error", error);
153
87
  throw error;
154
88
  }
155
89
  },
156
90
  documentChildren: async (_parent, args, ctx) => {
157
- this.logger.debug("documentChildren", args);
91
+ this.logger.debug("documentChildren(@args)", args);
158
92
  try {
159
- // First resolve the parent to get its ID and check permission
160
- const parent = await resolvers.document(this.reactorClient, {
161
- identifier: args.parentIdentifier,
162
- view: args.view,
163
- });
164
- if (parent) {
165
- await this.assertCanRead(parent.document.id, ctx);
166
- }
93
+ await this.assertCanRead(args.parentIdentifier, ctx);
167
94
  return await resolvers.documentChildren(this.reactorClient, args);
168
95
  }
169
96
  catch (error) {
170
- this.logger.error("Error in documentChildren:", error);
97
+ this.logger.error("Error in documentChildren: @Error", error);
171
98
  throw error;
172
99
  }
173
100
  },
174
101
  documentParents: async (_parent, args, ctx) => {
175
- this.logger.debug("documentParents", args);
102
+ this.logger.debug("documentParents(@args)", args);
176
103
  try {
177
- // First resolve the child to get its ID and check permission
178
- const child = await resolvers.document(this.reactorClient, {
179
- identifier: args.childIdentifier,
180
- view: args.view,
181
- });
182
- if (child) {
183
- await this.assertCanRead(child.document.id, ctx);
104
+ await this.assertCanRead(args.childIdentifier, ctx);
105
+ const result = await resolvers.documentParents(this.reactorClient, args);
106
+ // Filter results to only include documents the user can read
107
+ if (!this.hasGlobalAdminAccess(ctx) &&
108
+ this.documentPermissionService) {
109
+ const filteredItems = [];
110
+ for (const item of result.items) {
111
+ const canRead = await this.canReadDocument(item.id, ctx);
112
+ if (canRead) {
113
+ filteredItems.push(item);
114
+ }
115
+ }
116
+ return {
117
+ ...result,
118
+ items: filteredItems,
119
+ };
184
120
  }
185
- return await resolvers.documentParents(this.reactorClient, args);
121
+ return result;
186
122
  }
187
123
  catch (error) {
188
- this.logger.error("Error in documentParents:", error);
124
+ this.logger.error("Error in documentParents: @Error", error);
189
125
  throw error;
190
126
  }
191
127
  },
192
128
  findDocuments: async (_parent, args, ctx) => {
193
- this.logger.debug("findDocuments", args);
129
+ this.logger.debug("findDocuments(@args)", args);
194
130
  try {
195
131
  const result = await resolvers.findDocuments(this.reactorClient, args);
196
132
  // Filter results to only include documents the user can read
197
- if (!this.hasGlobalReadAccess(ctx) &&
133
+ if (!this.hasGlobalAdminAccess(ctx) &&
198
134
  this.documentPermissionService) {
199
135
  const filteredItems = [];
200
136
  for (const item of result.items) {
@@ -206,275 +142,262 @@ export class ReactorSubgraph extends BaseSubgraph {
206
142
  return {
207
143
  ...result,
208
144
  items: filteredItems,
209
- totalCount: filteredItems.length,
210
145
  };
211
146
  }
212
147
  return result;
213
148
  }
214
149
  catch (error) {
215
- this.logger.error("Error in findDocuments:", error);
150
+ this.logger.error("Error in findDocuments: @Error", error);
216
151
  throw error;
217
152
  }
218
153
  },
219
154
  jobStatus: async (_parent, args) => {
220
- this.logger.debug("jobStatus", args);
155
+ this.logger.debug("jobStatus(@args)", args);
221
156
  try {
222
157
  return await resolvers.jobStatus(this.reactorClient, args);
223
158
  }
224
159
  catch (error) {
225
- this.logger.error("Error in jobStatus:", error);
160
+ this.logger.error("Error in jobStatus: @Error", error);
226
161
  throw error;
227
162
  }
228
163
  },
229
- pollSyncEnvelopes: async (_parent, args) => {
230
- this.logger.debug("pollSyncEnvelopes", args);
164
+ documentOperations: async (_parent, args, ctx) => {
165
+ this.logger.debug("documentOperations(@args)", args);
231
166
  try {
232
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
233
- return await resolvers.pollSyncEnvelopes(this.syncManager, args);
167
+ await this.assertCanRead(args.filter.documentId, ctx);
168
+ return await resolvers.documentOperations(this.reactorClient, args);
234
169
  }
235
170
  catch (error) {
236
- this.logger.error("Error in pollSyncEnvelopes: @Error", error);
171
+ this.logger.error("Error in documentOperations: @Error", error);
172
+ throw error;
173
+ }
174
+ },
175
+ pollSyncEnvelopes: (_parent, args) => {
176
+ this.logger.debug("pollSyncEnvelopes(@args)", args);
177
+ try {
178
+ const { envelopes, ackOrdinal, deadLetters } = resolvers.pollSyncEnvelopes(this.syncManager, args);
179
+ return {
180
+ envelopes,
181
+ ackOrdinal,
182
+ deadLetters,
183
+ };
184
+ }
185
+ catch (error) {
186
+ this.logger.error("Error in pollSyncEnvelopes(@args): @Error", error);
237
187
  throw error;
238
188
  }
239
189
  },
240
190
  },
241
191
  Mutation: {
242
192
  createDocument: async (_parent, args, ctx) => {
243
- this.logger.debug("createDocument", args);
193
+ this.logger.debug("createDocument(@args)", args);
244
194
  try {
245
195
  // If creating under a parent, check write permission on parent
246
196
  if (args.parentIdentifier) {
247
197
  const parent = await resolvers.document(this.reactorClient, {
248
198
  identifier: args.parentIdentifier,
249
199
  });
250
- if (parent) {
251
- await this.assertCanWrite(parent.document.id, ctx);
200
+ await this.assertCanWrite(parent.document.id, ctx);
201
+ }
202
+ else if (this.authorizationService) {
203
+ if (!ctx.user?.address) {
204
+ throw new GraphQLError("Forbidden: authentication required to create documents");
252
205
  }
253
206
  }
254
- else if (!this.hasGlobalWriteAccess(ctx)) {
207
+ else if (!this.hasGlobalAdminAccess(ctx)) {
255
208
  throw new GraphQLError("Forbidden: insufficient permissions to create documents");
256
209
  }
257
- return await resolvers.createDocument(this.reactorClient, args);
210
+ const result = await resolvers.createDocument(this.reactorClient, args);
211
+ // Auto-ownership: set creator as document owner
212
+ if (this.authorizationService && ctx.user?.address && result?.id) {
213
+ await this.documentPermissionService?.initializeDocumentProtection(result.id, ctx.user.address, this.authorizationService.config.defaultProtection);
214
+ }
215
+ return result;
258
216
  }
259
217
  catch (error) {
260
- this.logger.error("Error in createDocument:", error);
218
+ this.logger.error("Error in createDocument(@args): @Error", error);
261
219
  throw error;
262
220
  }
263
221
  },
264
222
  createEmptyDocument: async (_parent, args, ctx) => {
265
- this.logger.debug("createEmptyDocument", args);
223
+ this.logger.debug("createEmptyDocument(@args)", args);
266
224
  try {
267
225
  // If creating under a parent, check write permission on parent
268
226
  if (args.parentIdentifier) {
269
227
  const parent = await resolvers.document(this.reactorClient, {
270
228
  identifier: args.parentIdentifier,
271
229
  });
272
- if (parent) {
273
- await this.assertCanWrite(parent.document.id, ctx);
230
+ await this.assertCanWrite(parent.document.id, ctx);
231
+ }
232
+ else if (this.authorizationService) {
233
+ if (!ctx.user?.address) {
234
+ throw new GraphQLError("Forbidden: authentication required to create documents");
274
235
  }
275
236
  }
276
- else if (!this.hasGlobalWriteAccess(ctx)) {
237
+ else if (!this.hasGlobalAdminAccess(ctx)) {
277
238
  throw new GraphQLError("Forbidden: insufficient permissions to create documents");
278
239
  }
279
- return await resolvers.createEmptyDocument(this.reactorClient, args);
240
+ const result = await resolvers.createEmptyDocument(this.reactorClient, args);
241
+ // Auto-ownership: set creator as document owner
242
+ if (this.authorizationService && ctx.user?.address && result?.id) {
243
+ await this.documentPermissionService?.initializeDocumentProtection(result.id, ctx.user.address, this.authorizationService.config.defaultProtection);
244
+ }
245
+ return result;
280
246
  }
281
247
  catch (error) {
282
- this.logger.error("Error in createEmptyDocument:", error);
248
+ this.logger.error("Error in createEmptyDocument(@args): @Error", error);
283
249
  throw error;
284
250
  }
285
251
  },
286
252
  mutateDocument: async (_parent, args, ctx) => {
287
- this.logger.debug("mutateDocument", args);
253
+ this.logger.debug("mutateDocument(@args)", args);
288
254
  try {
289
- // Resolve document and check write permission
290
- const doc = await resolvers.document(this.reactorClient, {
291
- identifier: args.documentIdentifier,
292
- view: args.view,
293
- });
294
- if (doc) {
295
- await this.assertCanWrite(doc.document.id, ctx);
296
- // Check operation-level permissions for each action
297
- await this.assertCanExecuteOperations(doc.document.id, args.actions, ctx);
255
+ // assertCanExecuteOperations uses canMutate (which combines write + operation checks)
256
+ // when authorizationService is available. For legacy fallback, assertCanWrite is needed.
257
+ if (!this.authorizationService) {
258
+ await this.assertCanWrite(args.documentIdentifier, ctx);
298
259
  }
260
+ // Check operation-level permissions for each action
261
+ await this.assertCanExecuteOperations(args.documentIdentifier, args.actions, ctx);
299
262
  return await resolvers.mutateDocument(this.reactorClient, args);
300
263
  }
301
264
  catch (error) {
302
- this.logger.error("Error in mutateDocument:", error);
265
+ this.logger.error("Error in mutateDocument(@args): @Error", error);
303
266
  throw error;
304
267
  }
305
268
  },
306
269
  mutateDocumentAsync: async (_parent, args, ctx) => {
307
- this.logger.debug("mutateDocumentAsync", args);
270
+ this.logger.debug("mutateDocumentAsync(@args)", args);
308
271
  try {
309
- // Resolve document and check write permission
310
- const doc = await resolvers.document(this.reactorClient, {
311
- identifier: args.documentIdentifier,
312
- view: args.view,
313
- });
314
- if (doc) {
315
- await this.assertCanWrite(doc.document.id, ctx);
316
- // Check operation-level permissions for each action
317
- await this.assertCanExecuteOperations(doc.document.id, args.actions, ctx);
272
+ if (!this.authorizationService) {
273
+ await this.assertCanWrite(args.documentIdentifier, ctx);
318
274
  }
275
+ // Check operation-level permissions for each action
276
+ await this.assertCanExecuteOperations(args.documentIdentifier, args.actions, ctx);
319
277
  return await resolvers.mutateDocumentAsync(this.reactorClient, args);
320
278
  }
321
279
  catch (error) {
322
- this.logger.error("Error in mutateDocumentAsync:", error);
280
+ this.logger.error("Error in mutateDocumentAsync(@args): @Error", error);
323
281
  throw error;
324
282
  }
325
283
  },
326
284
  renameDocument: async (_parent, args, ctx) => {
327
- this.logger.debug("renameDocument", args);
285
+ this.logger.debug("renameDocument(@args)", args);
328
286
  try {
329
- // Resolve document and check write permission
330
- const doc = await resolvers.document(this.reactorClient, {
331
- identifier: args.documentIdentifier,
332
- });
333
- if (doc) {
334
- await this.assertCanWrite(doc.document.id, ctx);
335
- }
287
+ await this.assertCanWrite(args.documentIdentifier, ctx);
336
288
  return await resolvers.renameDocument(this.reactorClient, args);
337
289
  }
338
290
  catch (error) {
339
- this.logger.error("Error in renameDocument:", error);
291
+ this.logger.error("Error in renameDocument(@args): @Error", error);
340
292
  throw error;
341
293
  }
342
294
  },
343
295
  addChildren: async (_parent, args, ctx) => {
344
- this.logger.debug("addChildren", args);
296
+ this.logger.debug("addChildren(@args)", args);
345
297
  try {
346
- // Check write permission on parent
347
- const parent = await resolvers.document(this.reactorClient, {
348
- identifier: args.parentIdentifier,
349
- });
350
- if (parent) {
351
- await this.assertCanWrite(parent.document.id, ctx);
352
- }
298
+ await this.assertCanWrite(args.parentIdentifier, ctx);
353
299
  return await resolvers.addChildren(this.reactorClient, args);
354
300
  }
355
301
  catch (error) {
356
- this.logger.error("Error in addChildren:", error);
302
+ this.logger.error("Error in addChildren(@args): @Error", error);
357
303
  throw error;
358
304
  }
359
305
  },
360
306
  removeChildren: async (_parent, args, ctx) => {
361
- this.logger.debug("removeChildren", args);
307
+ this.logger.debug("removeChildren(@args)", args);
362
308
  try {
363
- // Check write permission on parent
364
- const parent = await resolvers.document(this.reactorClient, {
365
- identifier: args.parentIdentifier,
366
- });
367
- if (parent) {
368
- await this.assertCanWrite(parent.document.id, ctx);
369
- }
309
+ await this.assertCanWrite(args.parentIdentifier, ctx);
370
310
  return await resolvers.removeChildren(this.reactorClient, args);
371
311
  }
372
312
  catch (error) {
373
- this.logger.error("Error in removeChildren:", error);
313
+ this.logger.error("Error in removeChildren(@args): @Error", error);
374
314
  throw error;
375
315
  }
376
316
  },
377
317
  moveChildren: async (_parent, args, ctx) => {
378
- this.logger.debug("moveChildren", args);
318
+ this.logger.debug("moveChildren(@args)", args);
379
319
  try {
380
- // Check write permission on both source and target parents
381
- const sourceParent = await resolvers.document(this.reactorClient, {
382
- identifier: args.sourceParentIdentifier,
383
- });
384
- if (sourceParent) {
385
- await this.assertCanWrite(sourceParent.document.id, ctx);
386
- }
387
- const targetParent = await resolvers.document(this.reactorClient, {
388
- identifier: args.targetParentIdentifier,
389
- });
390
- if (targetParent) {
391
- await this.assertCanWrite(targetParent.document.id, ctx);
392
- }
320
+ await this.assertCanWrite(args.sourceParentIdentifier, ctx);
321
+ await this.assertCanWrite(args.targetParentIdentifier, ctx);
393
322
  return await resolvers.moveChildren(this.reactorClient, args);
394
323
  }
395
324
  catch (error) {
396
- this.logger.error("Error in moveChildren:", error);
325
+ this.logger.error("Error in moveChildren(@args): @Error @args", error, args);
397
326
  throw error;
398
327
  }
399
328
  },
400
329
  deleteDocument: async (_parent, args, ctx) => {
401
- this.logger.debug("deleteDocument", args);
330
+ this.logger.debug("deleteDocument(@args)", args);
402
331
  try {
403
- // Check write permission on document
404
- const doc = await resolvers.document(this.reactorClient, {
405
- identifier: args.identifier,
406
- });
407
- if (doc) {
408
- await this.assertCanWrite(doc.document.id, ctx);
409
- }
332
+ await this.assertCanWrite(args.identifier, ctx);
410
333
  return await resolvers.deleteDocument(this.reactorClient, args);
411
334
  }
412
335
  catch (error) {
413
- this.logger.error("Error in deleteDocument:", error);
336
+ this.logger.error("Error in deleteDocument(@args): @Error", error);
414
337
  throw error;
415
338
  }
416
339
  },
417
340
  deleteDocuments: async (_parent, args, ctx) => {
418
- this.logger.debug("deleteDocuments", args);
341
+ this.logger.debug("deleteDocuments(@args)", args);
419
342
  try {
420
343
  // Check write permission on each document
421
344
  for (const identifier of args.identifiers) {
422
- const doc = await resolvers.document(this.reactorClient, {
423
- identifier,
424
- });
425
- if (doc) {
426
- await this.assertCanWrite(doc.document.id, ctx);
427
- }
345
+ await this.assertCanWrite(identifier, ctx);
428
346
  }
429
347
  return await resolvers.deleteDocuments(this.reactorClient, args);
430
348
  }
431
349
  catch (error) {
432
- this.logger.error("Error in deleteDocuments:", error);
350
+ this.logger.error("Error in deleteDocuments(@args): @Error", error);
433
351
  throw error;
434
352
  }
435
353
  },
436
354
  touchChannel: async (_parent, args) => {
437
- this.logger.debug("touchChannel", args);
355
+ this.logger.debug("touchChannel(@args)", args);
438
356
  try {
439
357
  return await resolvers.touchChannel(this.syncManager, args);
440
358
  }
441
359
  catch (error) {
442
- this.logger.error("Error in touchChannel:", error);
360
+ this.logger.error("Error in touchChannel(@args): @Error", error);
443
361
  throw error;
444
362
  }
445
363
  },
446
- pushSyncEnvelope: async (_parent, args) => {
447
- this.logger.debug("pushSyncEnvelope(@args)", args);
364
+ pushSyncEnvelopes: async (_parent, args) => {
365
+ this.logger.debug("pushSyncEnvelopes(@args)", args);
448
366
  try {
449
367
  // Convert readonly arrays to mutable arrays for the resolver
450
368
  const mutableArgs = {
451
- envelope: {
452
- type: args.envelope.type,
453
- channelMeta: { id: args.envelope.channelMeta.id },
454
- operations: args.envelope.operations
455
- ? args.envelope.operations.map((op) => ({
369
+ envelopes: args.envelopes.map((envelope) => ({
370
+ type: envelope.type,
371
+ channelMeta: { id: envelope.channelMeta.id },
372
+ operations: envelope.operations
373
+ ? envelope.operations.map((op) => ({
456
374
  operation: op.operation,
457
375
  context: {
458
376
  documentId: op.context.documentId,
459
377
  documentType: op.context.documentType,
460
378
  scope: op.context.scope,
461
379
  branch: op.context.branch,
380
+ ordinal: op.context.ordinal,
462
381
  },
463
382
  }))
464
383
  : null,
465
- cursor: args.envelope.cursor
384
+ cursor: envelope.cursor
466
385
  ? {
467
- remoteName: args.envelope.cursor.remoteName,
468
- cursorOrdinal: args.envelope.cursor.cursorOrdinal,
469
- lastSyncedAtUtcMs: args.envelope.cursor.lastSyncedAtUtcMs,
386
+ remoteName: envelope.cursor.remoteName,
387
+ cursorOrdinal: envelope.cursor.cursorOrdinal,
388
+ lastSyncedAtUtcMs: envelope.cursor.lastSyncedAtUtcMs,
470
389
  }
471
390
  : null,
472
- },
391
+ key: envelope.key ?? undefined,
392
+ dependsOn: envelope.dependsOn
393
+ ? [...envelope.dependsOn]
394
+ : undefined,
395
+ })),
473
396
  };
474
- return await resolvers.pushSyncEnvelope(this.syncManager, mutableArgs);
397
+ return await resolvers.pushSyncEnvelopes(this.syncManager, mutableArgs);
475
398
  }
476
399
  catch (error) {
477
- this.logger.error("Error in pushSyncEnvelope:", error);
400
+ this.logger.error("Error in pushSyncEnvelopes(@args): @Error", error);
478
401
  throw error;
479
402
  }
480
403
  },
@@ -485,7 +408,7 @@ export class ReactorSubgraph extends BaseSubgraph {
485
408
  subscribe: withFilter(
486
409
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
487
410
  (() => {
488
- this.logger.debug("documentChanges subscription started");
411
+ this.logger.debug("documentChanges(@args) subscription started");
489
412
  ensureGlobalDocumentSubscription(this.reactorClient);
490
413
  return getPubSub().asyncIterableIterator(SUBSCRIPTION_TRIGGERS.DOCUMENT_CHANGES);
491
414
  }),
@@ -509,7 +432,7 @@ export class ReactorSubgraph extends BaseSubgraph {
509
432
  subscribe: withFilter(
510
433
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
511
434
  ((_parent, args) => {
512
- this.logger.debug("jobChanges subscription", args);
435
+ this.logger.debug("jobChanges(@args) subscription started", args);
513
436
  ensureJobSubscription(this.reactorClient, args.jobId);
514
437
  return getPubSub().asyncIterableIterator(SUBSCRIPTION_TRIGGERS.JOB_CHANGES);
515
438
  }),