@powerhousedao/reactor-api 1.21.2 → 1.22.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 (134) hide show
  1. package/dist/index.d.ts +8 -503
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +7 -27020
  4. package/dist/src/processors/analytics-processor.d.ts +9 -0
  5. package/dist/src/processors/analytics-processor.d.ts.map +1 -0
  6. package/dist/src/processors/analytics-processor.js +9 -0
  7. package/dist/src/processors/index.d.ts +5 -0
  8. package/dist/src/processors/index.d.ts.map +1 -0
  9. package/dist/src/processors/index.js +4 -0
  10. package/dist/src/processors/manager.d.ts +14 -0
  11. package/dist/src/processors/manager.d.ts.map +1 -0
  12. package/dist/src/processors/manager.js +40 -0
  13. package/dist/src/processors/operational-processor.d.ts +8 -0
  14. package/dist/src/processors/operational-processor.d.ts.map +1 -0
  15. package/dist/src/processors/operational-processor.js +12 -0
  16. package/dist/src/processors/processor.d.ts +20 -0
  17. package/dist/src/processors/processor.d.ts.map +1 -0
  18. package/dist/src/processors/processor.js +45 -0
  19. package/dist/src/server.d.ts +18 -0
  20. package/dist/src/server.d.ts.map +1 -0
  21. package/dist/src/server.js +51 -0
  22. package/dist/src/subgraphs/analytics/index.d.ts +16 -0
  23. package/dist/src/subgraphs/analytics/index.d.ts.map +1 -0
  24. package/dist/src/subgraphs/analytics/index.js +85 -0
  25. package/dist/src/subgraphs/auth/env/getters.d.ts +3 -0
  26. package/dist/src/subgraphs/auth/env/getters.d.ts.map +1 -0
  27. package/dist/src/subgraphs/auth/env/getters.js +26 -0
  28. package/dist/src/subgraphs/auth/env/index.d.ts +8 -0
  29. package/dist/src/subgraphs/auth/env/index.d.ts.map +1 -0
  30. package/{src/subgraphs/auth/env/index.ts → dist/src/subgraphs/auth/env/index.js} +4 -6
  31. package/dist/src/subgraphs/auth/index.d.ts +11 -0
  32. package/dist/src/subgraphs/auth/index.d.ts.map +1 -0
  33. package/dist/src/subgraphs/auth/index.js +259 -0
  34. package/dist/src/subgraphs/auth/types.d.ts +35 -0
  35. package/dist/src/subgraphs/auth/types.d.ts.map +1 -0
  36. package/dist/src/subgraphs/auth/types.js +1 -0
  37. package/dist/src/subgraphs/auth/utils/helpers.d.ts +12 -0
  38. package/dist/src/subgraphs/auth/utils/helpers.d.ts.map +1 -0
  39. package/dist/src/subgraphs/auth/utils/helpers.js +100 -0
  40. package/dist/src/subgraphs/auth/utils/session.d.ts +22 -0
  41. package/dist/src/subgraphs/auth/utils/session.d.ts.map +1 -0
  42. package/dist/src/subgraphs/auth/utils/session.js +100 -0
  43. package/dist/src/subgraphs/auth/utils/user.d.ts +12 -0
  44. package/dist/src/subgraphs/auth/utils/user.d.ts.map +1 -0
  45. package/dist/src/subgraphs/auth/utils/user.js +26 -0
  46. package/dist/src/subgraphs/base/index.d.ts +16 -0
  47. package/dist/src/subgraphs/base/index.d.ts.map +1 -0
  48. package/dist/src/subgraphs/base/index.js +25 -0
  49. package/dist/src/subgraphs/drive/index.d.ts +11 -0
  50. package/dist/src/subgraphs/drive/index.d.ts.map +1 -0
  51. package/dist/src/subgraphs/drive/index.js +341 -0
  52. package/dist/src/subgraphs/drive/temp-hack-rwa-type-defs.d.ts +57 -0
  53. package/dist/src/subgraphs/drive/temp-hack-rwa-type-defs.d.ts.map +1 -0
  54. package/dist/src/subgraphs/drive/temp-hack-rwa-type-defs.js +1 -0
  55. package/dist/src/subgraphs/index.d.ts +10 -0
  56. package/dist/src/subgraphs/index.d.ts.map +1 -0
  57. package/dist/src/subgraphs/index.js +20 -0
  58. package/dist/src/subgraphs/manager.d.ts +23 -0
  59. package/dist/src/subgraphs/manager.d.ts.map +1 -0
  60. package/dist/src/subgraphs/manager.js +102 -0
  61. package/dist/src/subgraphs/system/env/getters.d.ts +2 -0
  62. package/dist/src/subgraphs/system/env/getters.d.ts.map +1 -0
  63. package/dist/src/subgraphs/system/env/getters.js +3 -0
  64. package/dist/src/subgraphs/system/env/index.d.ts +2 -0
  65. package/dist/src/subgraphs/system/env/index.d.ts.map +1 -0
  66. package/{src/subgraphs/system/env/index.ts → dist/src/subgraphs/system/env/index.js} +1 -3
  67. package/dist/src/subgraphs/system/index.d.ts +19 -0
  68. package/dist/src/subgraphs/system/index.d.ts.map +1 -0
  69. package/dist/src/subgraphs/system/index.js +63 -0
  70. package/dist/src/subgraphs/system/types.d.ts +5 -0
  71. package/dist/src/subgraphs/system/types.d.ts.map +1 -0
  72. package/dist/src/subgraphs/system/types.js +1 -0
  73. package/dist/src/subgraphs/types.d.ts +27 -0
  74. package/dist/src/subgraphs/types.d.ts.map +1 -0
  75. package/dist/src/subgraphs/types.js +1 -0
  76. package/dist/src/sync/utils.d.ts +13 -0
  77. package/dist/src/sync/utils.d.ts.map +1 -0
  78. package/dist/src/sync/utils.js +37 -0
  79. package/dist/src/types.d.ts +29 -0
  80. package/dist/src/types.d.ts.map +1 -0
  81. package/dist/src/types.js +1 -0
  82. package/dist/src/utils/create-schema.d.ts +7 -0
  83. package/dist/src/utils/create-schema.d.ts.map +1 -0
  84. package/dist/src/utils/create-schema.js +122 -0
  85. package/dist/src/utils/db.d.ts +4 -0
  86. package/dist/src/utils/db.d.ts.map +1 -0
  87. package/dist/src/utils/db.js +20 -0
  88. package/dist/src/utils/index.d.ts +3 -0
  89. package/dist/src/utils/index.d.ts.map +1 -0
  90. package/dist/src/utils/index.js +2 -0
  91. package/dist/tsconfig.tsbuildinfo +1 -0
  92. package/dist/vitest.config.d.ts +3 -0
  93. package/dist/vitest.config.d.ts.map +1 -0
  94. package/dist/vitest.config.js +24 -0
  95. package/package.json +18 -9
  96. package/CHANGELOG.md +0 -39
  97. package/dist/index.js.map +0 -1
  98. package/src/index.ts +0 -7
  99. package/src/processors/analytics-processor.ts +0 -18
  100. package/src/processors/index.ts +0 -4
  101. package/src/processors/manager.ts +0 -75
  102. package/src/processors/operational-processor.ts +0 -20
  103. package/src/processors/processor.ts +0 -75
  104. package/src/server.ts +0 -65
  105. package/src/subgraphs/analytics/index.ts +0 -119
  106. package/src/subgraphs/auth/env/getters.ts +0 -30
  107. package/src/subgraphs/auth/index.ts +0 -321
  108. package/src/subgraphs/auth/types.ts +0 -39
  109. package/src/subgraphs/auth/utils/helpers.ts +0 -132
  110. package/src/subgraphs/auth/utils/session.ts +0 -144
  111. package/src/subgraphs/auth/utils/user.ts +0 -40
  112. package/src/subgraphs/base/index.ts +0 -34
  113. package/src/subgraphs/drive/index.ts +0 -434
  114. package/src/subgraphs/drive/temp-hack-rwa-type-defs.ts +0 -39
  115. package/src/subgraphs/index.ts +0 -24
  116. package/src/subgraphs/manager.ts +0 -128
  117. package/src/subgraphs/system/env/getters.ts +0 -7
  118. package/src/subgraphs/system/index.ts +0 -73
  119. package/src/subgraphs/system/types.ts +0 -5
  120. package/src/subgraphs/types.ts +0 -29
  121. package/src/sync/utils.ts +0 -85
  122. package/src/types.ts +0 -43
  123. package/src/utils/create-schema.ts +0 -160
  124. package/src/utils/db.ts +0 -26
  125. package/src/utils/index.ts +0 -2
  126. package/test/benchmarks/load.bench.ts +0 -78
  127. package/test/benchmarks/sync.bench.ts +0 -151
  128. package/test/data/BlocktowerAndromeda.zip +0 -0
  129. package/test/router.test.ts +0 -48
  130. package/tsconfig.json +0 -21
  131. package/tsdoc.json +0 -3
  132. package/tsup.config.ts +0 -17
  133. package/types.d.ts +0 -5
  134. package/vitest.config.ts +0 -28
@@ -1,434 +0,0 @@
1
- import { GraphQLResolverMap } from "@apollo/subgraph/dist/schema-helper";
2
- import { pascalCase } from "change-case";
3
- import {
4
- generateUUID,
5
- ListenerRevision,
6
- StrandUpdateGraphQL,
7
- } from "document-drive";
8
- import {
9
- actions,
10
- FileNode,
11
- Listener,
12
- ListenerFilter,
13
- TransmitterType,
14
- } from "document-model-libs/document-drive";
15
- import { Document, Operation } from "document-model/document";
16
- import {
17
- DocumentModelInput,
18
- DocumentModelState,
19
- } from "document-model/document-model";
20
- import { gql } from "graphql-tag";
21
- import {
22
- InternalStrandUpdate,
23
- processAcknowledge,
24
- processGetStrands,
25
- processPushUpdate,
26
- } from "src/sync/utils";
27
- import { Subgraph } from "../base";
28
- import { Context, SubgraphArgs } from "../types";
29
- import { Asset } from "./temp-hack-rwa-type-defs";
30
-
31
- const ENABLE_SYNC_DEBUG = false;
32
-
33
- const driveKindTypeNames: Record<string, string> = {
34
- file: "DocumentDrive_FileNode",
35
- folder: "DocumentDrive_FolderNode",
36
- };
37
-
38
- export class DriveSubgraph extends Subgraph {
39
- private debugID = `[DSG #${Math.floor(Math.random() * 999)}]`;
40
-
41
- constructor(args: SubgraphArgs) {
42
- super(args);
43
- this.debugLog(`constructor()`);
44
- }
45
-
46
- private debugLog(...data: any[]) {
47
- if (!ENABLE_SYNC_DEBUG) {
48
- return;
49
- }
50
-
51
- if (data.length > 0 && typeof data[0] === "string") {
52
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
53
- console.log(`${this.debugID} ${data[0]}`, ...data.slice(1));
54
- } else {
55
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
56
- console.log(this.debugID, ...data);
57
- }
58
- }
59
-
60
- name = "d/:drive";
61
- typeDefs = gql`
62
- type Query {
63
- system: System
64
- drive: DocumentDrive_DocumentDriveState
65
- document(id: String!): IDocument
66
- documents: [String!]!
67
- }
68
-
69
- type Mutation {
70
- registerPullResponderListener(
71
- filter: InputListenerFilter!
72
- ): DocumentDrive_Listener
73
- pushUpdates(strands: [InputStrandUpdate!]): [ListenerRevision!]!
74
- acknowledge(
75
- listenerId: String!
76
- revisions: [ListenerRevisionInput]
77
- ): Boolean
78
- }
79
-
80
- input InputOperationSignerUser {
81
- address: String!
82
- networkId: String!
83
- chainId: Int!
84
- }
85
-
86
- type OperationSignerUser {
87
- address: String!
88
- networkId: String!
89
- chainId: Int!
90
- }
91
-
92
- input InputOperationSignerApp {
93
- name: String!
94
- key: String!
95
- }
96
-
97
- type OperationSignerApp {
98
- name: String!
99
- key: String!
100
- }
101
-
102
- type OperationSigner {
103
- app: OperationSignerApp
104
- user: OperationSignerUser
105
- signatures: [[String!]]!
106
- }
107
-
108
- input InputOperationSigner {
109
- app: InputOperationSignerApp
110
- user: InputOperationSignerUser
111
- signatures: [[String!]]!
112
- }
113
-
114
- type OperationContext {
115
- signer: OperationSigner
116
- }
117
-
118
- input InputOperationContext {
119
- signer: InputOperationSigner
120
- }
121
-
122
- input InputOperationUpdate {
123
- index: Int!
124
- skip: Int
125
- type: String!
126
- id: String!
127
- input: String!
128
- hash: String!
129
- timestamp: String!
130
- error: String
131
- context: InputOperationContext
132
- }
133
-
134
- type OperationUpdate {
135
- index: Int!
136
- skip: Int
137
- type: String!
138
- id: String!
139
- input: String!
140
- hash: String!
141
- timestamp: String!
142
- error: String
143
- context: OperationContext
144
- }
145
-
146
- type StrandUpdate {
147
- driveId: String!
148
- documentId: String!
149
- scope: String!
150
- branch: String!
151
- operations: [OperationUpdate!]!
152
- }
153
-
154
- input InputStrandUpdate {
155
- driveId: String!
156
- documentId: String!
157
- scope: String!
158
- branch: String!
159
- operations: [InputOperationUpdate!]!
160
- }
161
-
162
- input InputListenerFilter {
163
- documentType: [String!]
164
- documentId: [String!]
165
- scope: [String!]
166
- branch: [String!]
167
- }
168
-
169
- enum UpdateStatus {
170
- SUCCESS
171
- MISSING
172
- CONFLICT
173
- ERROR
174
- }
175
-
176
- input ListenerRevisionInput {
177
- driveId: String!
178
- documentId: String!
179
- scope: String!
180
- branch: String!
181
- status: UpdateStatus!
182
- revision: Int!
183
- }
184
-
185
- type ListenerRevision {
186
- driveId: String!
187
- documentId: String!
188
- scope: String!
189
- branch: String!
190
- status: UpdateStatus!
191
- revision: Int!
192
- error: String
193
- }
194
-
195
- type System {
196
- sync: Sync
197
- }
198
-
199
- type Sync {
200
- strands(listenerId: ID!, since: String): [StrandUpdate!]!
201
- }
202
- `;
203
-
204
- resolvers: GraphQLResolverMap<Context> = {
205
- Asset: {
206
- __resolveType: (obj: Asset) => {
207
- return obj.type;
208
- },
209
- },
210
- Node: {
211
- __resolveType: (obj: FileNode) => {
212
- return obj.documentType ? "FileNode" : "FolderNode";
213
- },
214
- },
215
- Document: {
216
- operations: async (
217
- obj: Document,
218
- { first, skip }: { first: number; skip: number },
219
- ctx: Context,
220
- ) => {
221
- const limit = first ?? 0;
222
- const start = skip ?? 0;
223
- return obj.operations.global.slice(start, start + limit);
224
- },
225
- },
226
- Query: {
227
- drive: async (_: unknown, args: unknown, ctx: Context) => {
228
- this.debugLog(`drive()`, args);
229
- if (!ctx.driveId) throw new Error("Drive ID is required");
230
- const drive = await this.reactor.getDrive(ctx.driveId);
231
- return {
232
- ...drive.state.global,
233
- nodes: drive.state.global.nodes.map((n) => ({
234
- ...n,
235
- __typename: driveKindTypeNames[n.kind] || "UnkownDriveNode",
236
- })),
237
- };
238
- },
239
- documents: async (_: unknown, args: unknown, ctx: Context) => {
240
- this.debugLog(`documents(drive: ${ctx.driveId})`, args);
241
- if (!ctx.driveId) throw new Error("Drive ID is required");
242
- const documents = await this.reactor.getDocuments(ctx.driveId);
243
- return documents;
244
- },
245
- document: async (_: unknown, { id }: { id: string }, ctx: Context) => {
246
- this.debugLog(`document(drive: ${ctx.driveId}, id: ${id})`);
247
- if (!ctx.driveId) throw new Error("Drive ID is required");
248
- const document = await this.reactor.getDocument(ctx.driveId, id);
249
-
250
- const dms = this.reactor.getDocumentModels();
251
- const dm = dms.find(
252
- ({ documentModel }: { documentModel: DocumentModelState }) =>
253
- documentModel.id === document.documentType,
254
- );
255
- const globalState = document.state.global;
256
- if (!globalState) throw new Error("Document not found");
257
- const typeName = pascalCase(
258
- (dm?.documentModel.name || "").replaceAll("/", " "),
259
- );
260
- const response = {
261
- ...document,
262
- id,
263
- revision: document.revision.global,
264
- state: document.state.global,
265
- operations: document.operations.global.map((op: Operation) => ({
266
- ...op,
267
- inputText:
268
- typeof op.input === "string"
269
- ? op.input
270
- : JSON.stringify(op.input),
271
- })),
272
- initialState: document.initialState.state.global,
273
- __typename: typeName,
274
- };
275
- return response;
276
- },
277
- system: () => ({ sync: {} }),
278
- },
279
- Mutation: {
280
- registerPullResponderListener: async (
281
- _: unknown,
282
- { filter }: { filter: ListenerFilter },
283
- ctx: Context,
284
- ) => {
285
- this.debugLog(
286
- `registerPullResponderListener(drive: ${ctx.driveId})`,
287
- filter,
288
- );
289
-
290
- if (!ctx.driveId) throw new Error("Drive ID is required");
291
- const uuid = generateUUID();
292
- const listener: Listener = {
293
- block: false,
294
- callInfo: {
295
- data: "",
296
- name: "PullResponder",
297
- transmitterType: "PullResponder" as TransmitterType,
298
- },
299
- filter: {
300
- branch: filter.branch ?? [],
301
- documentId: filter.documentId ?? [],
302
- documentType: filter.documentType ?? [],
303
- scope: filter.scope ?? [],
304
- },
305
- label: `Pullresponder #${uuid}`,
306
- listenerId: uuid,
307
- system: false,
308
- };
309
-
310
- const result = await this.reactor.queueDriveAction(
311
- ctx.driveId,
312
- actions.addListener({ listener }),
313
- );
314
-
315
- if (result.status !== "SUCCESS" && result.error) {
316
- throw new Error(
317
- `Listener couldn't be registered: ${result.error.message}`,
318
- );
319
- }
320
-
321
- return listener;
322
- },
323
- pushUpdates: async (
324
- _: unknown,
325
- { strands: strandsGql }: { strands: StrandUpdateGraphQL[] },
326
- ctx: Context,
327
- ) => {
328
- if (!ctx.driveId) throw new Error("Drive ID is required");
329
- this.debugLog(`pushUpdates(drive: ${ctx.driveId})`, strandsGql);
330
-
331
- // translate data types
332
- const strands: InternalStrandUpdate[] = strandsGql.map((strandGql) => {
333
- return {
334
- operations: strandGql.operations.map((op) => ({
335
- ...op,
336
- input: JSON.parse(op.input) as DocumentModelInput,
337
- skip: op.skip ?? 0,
338
- scope: strandGql.scope,
339
- branch: "main",
340
- })) as Operation[],
341
- documentId: strandGql.documentId,
342
- driveId: strandGql.driveId,
343
- scope: strandGql.scope,
344
- branch: strandGql.branch,
345
- };
346
- });
347
-
348
- // return a list of listener revisions
349
- return await Promise.all(
350
- strands.map((strand) => processPushUpdate(this.reactor, strand)),
351
- );
352
- },
353
- acknowledge: async (
354
- _: unknown,
355
- {
356
- listenerId,
357
- revisions,
358
- }: { listenerId: string; revisions: ListenerRevision[] },
359
- ctx: Context,
360
- ) => {
361
- this.debugLog(
362
- `acknowledge(drive: ${ctx.driveId}, listenerId: ${listenerId})`,
363
- revisions,
364
- );
365
-
366
- if (!listenerId || !revisions) return false;
367
- if (!ctx.driveId) throw new Error("Drive ID is required");
368
-
369
- // translate data types
370
- const validEntries = revisions
371
- .filter((r) => r !== null)
372
- .map((e) => ({
373
- driveId: e.driveId,
374
- documentId: e.documentId,
375
- scope: e.scope,
376
- branch: e.branch,
377
- revision: e.revision,
378
- status: e.status,
379
- }));
380
-
381
- // return a boolean indicating if the acknowledge was successful
382
- return await processAcknowledge(
383
- this.reactor,
384
- ctx.driveId,
385
- listenerId,
386
- validEntries,
387
- );
388
- },
389
- },
390
- System: {},
391
- Sync: {
392
- strands: async (
393
- _: unknown,
394
- {
395
- listenerId,
396
- since,
397
- }: { listenerId: string; since: string | undefined },
398
- ctx: Context,
399
- ) => {
400
- this.debugLog(
401
- `strands(drive: ${ctx.driveId}, listenerId: ${listenerId}, since:${since})`,
402
- );
403
- if (!ctx.driveId) throw new Error("Drive ID is required");
404
-
405
- // get the requested strand updates
406
- const strands = await processGetStrands(
407
- this.reactor,
408
- ctx.driveId,
409
- listenerId,
410
- since,
411
- );
412
-
413
- // translate data types
414
- return strands.map((update) => ({
415
- driveId: update.driveId,
416
- documentId: update.documentId,
417
- scope: update.scope,
418
- branch: update.branch,
419
- operations: update.operations.map((op) => ({
420
- index: op.index,
421
- skip: op.skip,
422
- name: op.type,
423
- input: JSON.stringify(op.input),
424
- hash: op.hash,
425
- timestamp: op.timestamp,
426
- type: op.type,
427
- context: op.context,
428
- id: op.id,
429
- })),
430
- }));
431
- },
432
- },
433
- };
434
- }
@@ -1,39 +0,0 @@
1
- import { Maybe } from "document-model/document-model";
2
-
3
- export type Scalars = {
4
- ID: { input: string; output: string };
5
- String: { input: string; output: string };
6
- Boolean: { input: boolean; output: boolean };
7
- Int: { input: number; output: number };
8
- Float: { input: number; output: number };
9
- DateTime: { input: string; output: string };
10
- };
11
- export type Asset = Cash | FixedIncome;
12
-
13
- export type AssetType = "Cash" | "FixedIncome";
14
- export type Cash = {
15
- balance: Scalars["Float"]["output"];
16
- currency: Scalars["String"]["output"];
17
- id: Scalars["ID"]["output"];
18
- spvId: Scalars["ID"]["output"];
19
- type: AssetType | `${AssetType}`;
20
- };
21
- export type FixedIncome = {
22
- CUSIP: Maybe<Scalars["String"]["output"]>;
23
- ISIN: Maybe<Scalars["String"]["output"]>;
24
- assetProceeds: Scalars["Float"]["output"];
25
- coupon: Maybe<Scalars["Float"]["output"]>;
26
- fixedIncomeTypeId: Scalars["ID"]["output"];
27
- id: Scalars["ID"]["output"];
28
- maturity: Maybe<Scalars["DateTime"]["output"]>;
29
- name: Scalars["String"]["output"];
30
- notional: Scalars["Float"]["output"];
31
- purchaseDate: Scalars["DateTime"]["output"];
32
- purchasePrice: Scalars["Float"]["output"];
33
- purchaseProceeds: Scalars["Float"]["output"];
34
- realizedSurplus: Scalars["Float"]["output"];
35
- salesProceeds: Scalars["Float"]["output"];
36
- spvId: Scalars["ID"]["output"];
37
- totalDiscount: Scalars["Float"]["output"];
38
- type: AssetType | `${AssetType}`;
39
- };
@@ -1,24 +0,0 @@
1
- import { Subgraph } from "./base";
2
-
3
- export * as analyticsSubgraph from "./analytics";
4
- export * as driveSubgraph from "./drive";
5
- export * as systemSubgraph from "./system";
6
- export * as authSubgraph from "./auth";
7
- export * from "./types";
8
- export { Subgraph } from "./base";
9
-
10
- export type SubgraphClass = typeof Subgraph;
11
- export function isSubgraphClass(
12
- candidate: unknown,
13
- ): candidate is SubgraphClass {
14
- if (typeof candidate !== "function") return false;
15
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
16
- let proto = Object.getPrototypeOf(candidate);
17
- while (proto) {
18
- if (Object.prototype.isPrototypeOf.call(proto, Subgraph)) return true;
19
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
20
- proto = Object.getPrototypeOf(proto);
21
- }
22
-
23
- return false;
24
- }
@@ -1,128 +0,0 @@
1
- import { ApolloServer } from "@apollo/server";
2
- import { expressMiddleware } from "@apollo/server/express4";
3
- import { ApolloServerPluginInlineTraceDisabled } from "@apollo/server/plugin/disabled";
4
- import { IAnalyticsStore } from "@powerhousedao/analytics-engine-core";
5
- import bodyParser from "body-parser";
6
- import cors from "cors";
7
- import { IDocumentDriveServer } from "document-drive";
8
- import express, { IRouter, Router } from "express";
9
- import { Db } from "src/types";
10
- import { authSubgraph, Context, SubgraphArgs, SubgraphClass } from ".";
11
- import { createSchema } from "../utils/create-schema";
12
- import { AnalyticsSubgraph } from "./analytics";
13
- import { Subgraph } from "./base";
14
- import { DriveSubgraph } from "./drive";
15
- import { SystemSubgraph } from "./system";
16
- import { AuthSubgraph } from "./auth";
17
-
18
- export class SubgraphManager {
19
- private reactorRouter: IRouter = Router();
20
- private contextFields: Record<string, any> = {};
21
- private subgraphs: Subgraph[] = [];
22
-
23
- constructor(
24
- private readonly path: string,
25
- private readonly app: express.Express,
26
- private readonly reactor: IDocumentDriveServer,
27
- private readonly operationalStore: Db,
28
- private readonly analyticsStore: IAnalyticsStore,
29
- ) {
30
- // Setup Default subgraphs
31
- this.registerSubgraph(AuthSubgraph);
32
- this.registerSubgraph(SystemSubgraph);
33
- this.registerSubgraph(DriveSubgraph);
34
- this.registerSubgraph(AnalyticsSubgraph);
35
- }
36
-
37
- async init() {
38
- console.log(`Initializing Subgraph Manager...`);
39
- const models = this.reactor.getDocumentModels();
40
- const driveModel = models.find(
41
- (it) => it.documentModel.name === "DocumentDrive",
42
- );
43
- if (!driveModel) {
44
- throw new Error("DocumentDrive model required");
45
- }
46
-
47
- this.reactor.on("documentModels", () => {
48
- this.updateRouter().catch((error: unknown) => console.error(error));
49
- });
50
-
51
- this.app.use(this.path, (req, res, next) =>
52
- this.reactorRouter(req, res, next),
53
- );
54
-
55
- await this.updateRouter();
56
- }
57
-
58
- async updateRouter() {
59
- const newRouter = Router();
60
- newRouter.use(cors());
61
- newRouter.use(bodyParser.json());
62
- // Run each subgraph on the same http server, but at different paths
63
- for (const subgraph of this.subgraphs) {
64
- const subgraphConfig = this.#getLocalSubgraphConfig(subgraph.name);
65
- if (!subgraphConfig) continue;
66
- // get schema
67
- const schema = createSchema(
68
- this.reactor,
69
- subgraphConfig.resolvers,
70
- subgraphConfig.typeDefs,
71
- );
72
- // create apollo server
73
- const server = new ApolloServer({
74
- schema,
75
- introspection: true,
76
- plugins: [ApolloServerPluginInlineTraceDisabled()],
77
- });
78
-
79
- // start apollo server
80
- await server.start();
81
-
82
- // setup path
83
- const path = `/${subgraphConfig.name}`;
84
- newRouter.use(
85
- path,
86
- // @ts-ignore
87
- expressMiddleware(server, {
88
- context: ({ req }): Context => ({
89
- headers: req.headers,
90
- driveId: req.params.drive ?? undefined,
91
- driveServer: this.reactor,
92
- db: this.operationalStore,
93
- ...this.getAdditionalContextFields(),
94
- }),
95
- }),
96
- );
97
- }
98
-
99
- this.reactorRouter = newRouter;
100
- }
101
-
102
- async registerSubgraph(subgraph: SubgraphClass) {
103
- const subgraphInstance = new subgraph({
104
- operationalStore: this.operationalStore,
105
- analyticsStore: this.analyticsStore,
106
- reactor: this.reactor,
107
- subgraphManager: this,
108
- });
109
- await subgraphInstance.onSetup();
110
- this.subgraphs.unshift(subgraphInstance);
111
- console.log(
112
- `> Registered ${this.path.endsWith("/") ? this.path : this.path + "/"}${subgraphInstance.name} subgraph.`,
113
- );
114
- await this.updateRouter();
115
- }
116
-
117
- #getLocalSubgraphConfig(subgraphName: string) {
118
- return this.subgraphs.find((it) => it.name === subgraphName);
119
- }
120
-
121
- getAdditionalContextFields = () => {
122
- return this.contextFields;
123
- };
124
-
125
- setAdditionalContextFields(fields: Record<string, any>) {
126
- this.contextFields = { ...this.contextFields, ...fields };
127
- }
128
- }
@@ -1,7 +0,0 @@
1
- export const getAdminUsers = (): string[] => {
2
- return (
3
- process.env.ADMIN_USERS?.split(",").map((user) =>
4
- user.trim().toLocaleLowerCase(),
5
- ) || []
6
- );
7
- };
@@ -1,73 +0,0 @@
1
- import { DriveInput } from "document-drive";
2
- import { GraphQLError } from "graphql";
3
- import { gql } from "graphql-tag";
4
- import { Subgraph } from "../base";
5
- import { ADMIN_USERS } from "./env";
6
- import { SystemContext } from "./types";
7
-
8
- export class SystemSubgraph extends Subgraph {
9
- name = "system";
10
-
11
- typeDefs = gql`
12
- type Query {
13
- drives: [String!]!
14
- driveIdBySlug(slug: String!): String
15
- }
16
-
17
- type Mutation {
18
- addDrive(
19
- global: DocumentDriveStateInput!
20
- ): DocumentDrive_DocumentDriveState
21
- deleteDrive(id: ID!): Boolean
22
- setDriveIcon(id: String!, icon: String!): Boolean
23
- setDriveName(id: String!, name: String!): Boolean
24
- }
25
-
26
- input DocumentDriveStateInput {
27
- name: String
28
- id: String
29
- slug: String
30
- icon: String
31
- }
32
- `;
33
-
34
- resolvers = {
35
- Query: {
36
- drives: async () => {
37
- return await this.reactor.getDrives();
38
- },
39
- },
40
- Mutation: {
41
- addDrive: async (
42
- parent: unknown,
43
- args: DriveInput,
44
- ctx: SystemContext,
45
- ) => {
46
- try {
47
- const isAdmin = ctx.isAdmin(ctx);
48
- if (!isAdmin) {
49
- throw new GraphQLError("Unauthorized");
50
- }
51
- const drive = await this.reactor.addDrive(args);
52
- return drive.state.global;
53
- } catch (e) {
54
- console.error(e);
55
- throw new Error(e as string);
56
- }
57
- },
58
- },
59
- };
60
-
61
- async onSetup() {
62
- await super.onSetup();
63
- this.subgraphManager.setAdditionalContextFields({
64
- isAdmin: (ctx: SystemContext) => {
65
- return (
66
- ADMIN_USERS.length === 0 ||
67
- (ctx.session.address &&
68
- ADMIN_USERS.includes(ctx.session.address.toLocaleLowerCase()))
69
- );
70
- },
71
- });
72
- }
73
- }
@@ -1,5 +0,0 @@
1
- import { AuthContext } from "../auth/types";
2
-
3
- export type SystemContext = AuthContext & {
4
- isAdmin: (ctx: AuthContext) => boolean;
5
- };