@powerhousedao/reactor-api 6.2.2-dev.5 → 6.2.2-dev.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +274 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +342 -52
- package/dist/index.mjs.map +1 -1
- package/dist/src/packages/vite-loader.d.mts +3 -2
- package/dist/src/packages/vite-loader.d.mts.map +1 -1
- package/dist/src/packages/vite-loader.mjs +16 -3
- package/dist/src/packages/vite-loader.mjs.map +1 -1
- package/dist/{types-DnHgkahK.d.mts → types-D2ZrjmCk.d.mts} +8 -2
- package/dist/types-D2ZrjmCk.d.mts.map +1 -0
- package/dist/{utils-iibOQ50e.mjs → utils-Tw4hVMpc.mjs} +86 -7
- package/dist/utils-Tw4hVMpc.mjs.map +1 -0
- package/package.json +14 -13
- package/dist/types-DnHgkahK.d.mts.map +0 -1
- package/dist/utils-iibOQ50e.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { a as isSubgraphClass,
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="50fb0cae-c1a3-5acc-9be1-417f9b1814c6")}catch(e){}}();
|
|
3
|
+
import { _ as createAuthorizationService, a as isSubgraphClass, d as loadSubgraphs, f as BaseSubgraph, g as AuthorizedDocumentHandle, h as AuthorizationPolicy, i as buildGraphqlOperations, l as loadDocumentModels, m as createCanonicalDocumentIdResolver, n as buildGraphQlDriveDocument, o as debounce, p as CanonicalDocumentIdResolutionError, r as buildGraphqlOperation, s as extractUpgradeManifests, t as buildGraphQlDocument, u as loadProcessors, v as AuthEvaluationUnsupportedError } from "./utils-Tw4hVMpc.mjs";
|
|
4
4
|
import { AnalyticsQueryEngine } from "@powerhousedao/analytics-engine-core";
|
|
5
5
|
import { AnalyticsModel, AnalyticsResolvers, typedefs } from "@powerhousedao/analytics-engine-graphql";
|
|
6
6
|
import { gql } from "graphql-tag";
|
|
7
7
|
import { GraphQLError, Kind, parse, print } from "graphql";
|
|
8
|
-
import { DEFAULT_DRIVE_CONTAINER_TYPES, DriveCollectionId, PropagationMode as PropagationMode$1, consolidateSyncOperations, driveIdFromUrl, envelopesToSyncOperations, parseDriveUrl } from "@powerhousedao/reactor";
|
|
8
|
+
import { AuthEnforcementDisabledError, DEFAULT_DRIVE_CONTAINER_TYPES, DriveCollectionId, PropagationMode as PropagationMode$1, consolidateSyncOperations, driveIdFromUrl, envelopesToSyncOperations, parseDriveUrl, syncOperationErrorType } from "@powerhousedao/reactor";
|
|
9
9
|
import { ConsoleLogger, childLogger, documentModelDocumentModelModule } from "document-model";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { match } from "path-to-regexp";
|
|
@@ -22,11 +22,12 @@ import dotenv from "dotenv";
|
|
|
22
22
|
import { buildTreeUrl } from "@powerhousedao/shared";
|
|
23
23
|
import { getConfig } from "@powerhousedao/config/node";
|
|
24
24
|
import { reactorDriveDocumentModelModule } from "@powerhousedao/reactor-drive";
|
|
25
|
+
import { ReactorGroupV1 } from "@powerhousedao/reactor-group";
|
|
25
26
|
import { driveDocumentModelModule } from "@powerhousedao/shared/document-drive";
|
|
26
27
|
import EventEmitter from "node:events";
|
|
27
28
|
import fs, { watchFile } from "node:fs";
|
|
28
29
|
import { PostgresAnalyticsStore } from "@powerhousedao/analytics-engine-pg";
|
|
29
|
-
import { AttachmentBuilder } from "@powerhousedao/reactor-attachments";
|
|
30
|
+
import { AttachmentBuilder, AttachmentReferenceIndexBuilder, createRef, createS3AttachmentBackend, parseAttachmentStorageConfig, parseRef } from "@powerhousedao/reactor-attachments";
|
|
30
31
|
import { createAttachmentClient } from "@powerhousedao/reactor-attachments/client";
|
|
31
32
|
import { setupMcpServer } from "@powerhousedao/reactor-mcp";
|
|
32
33
|
import { mkdir } from "node:fs/promises";
|
|
@@ -34,7 +35,7 @@ import { tmpdir } from "node:os";
|
|
|
34
35
|
import { WebSocketServer } from "ws";
|
|
35
36
|
import { createRelationalDb } from "@powerhousedao/shared/processors";
|
|
36
37
|
import { Kysely, Migrator, sql } from "kysely";
|
|
37
|
-
import { fetchDelegationCredential, verifyAuthBearerToken } from "@renown/sdk";
|
|
38
|
+
import { fetchDelegationCredential, resolveSwitchboardEndpoint, verifyAuthBearerToken } from "@renown/sdk";
|
|
38
39
|
import { PGlite } from "@electric-sql/pglite";
|
|
39
40
|
import { AtomicNodeFs } from "@powerhousedao/pglite-fs";
|
|
40
41
|
import knex from "knex";
|
|
@@ -460,6 +461,7 @@ const getDocumentModelTypeDefs = (documentModels, typeDefs$1) => {
|
|
|
460
461
|
});
|
|
461
462
|
return dedupeTypeDefinitions(gql`
|
|
462
463
|
scalar JSONObject
|
|
464
|
+
scalar AttachmentRef
|
|
463
465
|
${typeDefs.join("\n").replaceAll(";", "")}
|
|
464
466
|
|
|
465
467
|
type PHOperationContext {
|
|
@@ -878,6 +880,7 @@ function generateNewApiSchema(documentName, specification, _stateSchemaTypes, pr
|
|
|
878
880
|
return gql`
|
|
879
881
|
scalar DateTime
|
|
880
882
|
scalar JSONObject
|
|
883
|
+
scalar AttachmentRef
|
|
881
884
|
|
|
882
885
|
${revisionType}
|
|
883
886
|
|
|
@@ -926,6 +929,11 @@ function generateNewApiSchema(documentName, specification, _stateSchemaTypes, pr
|
|
|
926
929
|
}
|
|
927
930
|
//#endregion
|
|
928
931
|
//#region src/graphql/reactor/gen/graphql.ts
|
|
932
|
+
let AuthDecision = /* @__PURE__ */ function(AuthDecision) {
|
|
933
|
+
AuthDecision["Allow"] = "ALLOW";
|
|
934
|
+
AuthDecision["Deny"] = "DENY";
|
|
935
|
+
return AuthDecision;
|
|
936
|
+
}({});
|
|
929
937
|
let DocumentChangeType = /* @__PURE__ */ function(DocumentChangeType) {
|
|
930
938
|
DocumentChangeType["ChildAdded"] = "CHILD_ADDED";
|
|
931
939
|
DocumentChangeType["ChildRemoved"] = "CHILD_REMOVED";
|
|
@@ -948,9 +956,17 @@ let SyncEnvelopeType = /* @__PURE__ */ function(SyncEnvelopeType) {
|
|
|
948
956
|
}({});
|
|
949
957
|
const isDefinedNonNullAny = (v) => v !== void 0 && v !== null;
|
|
950
958
|
const definedNonNullAnySchema = z$1.any().refine((v) => isDefinedNonNullAny(v));
|
|
959
|
+
const AuthDecisionSchema = z$1.enum(AuthDecision);
|
|
951
960
|
const DocumentChangeTypeSchema = z$1.enum(DocumentChangeType);
|
|
952
961
|
const PropagationModeSchema = z$1.enum(PropagationMode);
|
|
953
962
|
const SyncEnvelopeTypeSchema = z$1.enum(SyncEnvelopeType);
|
|
963
|
+
function ActionCandidateInputSchema() {
|
|
964
|
+
return z$1.object({
|
|
965
|
+
input: z$1.custom((v) => v != null).nullish(),
|
|
966
|
+
scope: z$1.string(),
|
|
967
|
+
type: z$1.string()
|
|
968
|
+
});
|
|
969
|
+
}
|
|
954
970
|
function ActionContextInputSchema() {
|
|
955
971
|
return z$1.object({ signer: z$1.lazy(() => ReactorSignerInputSchema().nullish()) });
|
|
956
972
|
}
|
|
@@ -989,6 +1005,7 @@ function OperationContextInputSchema() {
|
|
|
989
1005
|
function OperationInputSchema() {
|
|
990
1006
|
return z$1.object({
|
|
991
1007
|
action: z$1.lazy(() => ActionInputSchema()),
|
|
1008
|
+
deniedReason: z$1.string().nullish(),
|
|
992
1009
|
error: z$1.string().nullish(),
|
|
993
1010
|
hash: z$1.string(),
|
|
994
1011
|
id: z$1.string().nullish(),
|
|
@@ -1147,6 +1164,7 @@ const GetDocumentWithOperationsDocument = gql`
|
|
|
1147
1164
|
hash
|
|
1148
1165
|
skip
|
|
1149
1166
|
error
|
|
1167
|
+
deniedReason
|
|
1150
1168
|
id
|
|
1151
1169
|
action {
|
|
1152
1170
|
id
|
|
@@ -1259,6 +1277,7 @@ const GetDocumentOperationsDocument = gql`
|
|
|
1259
1277
|
hash
|
|
1260
1278
|
skip
|
|
1261
1279
|
error
|
|
1280
|
+
deniedReason
|
|
1262
1281
|
id
|
|
1263
1282
|
action {
|
|
1264
1283
|
id
|
|
@@ -1301,6 +1320,28 @@ const GetJobStatusDocument = gql`
|
|
|
1301
1320
|
}
|
|
1302
1321
|
}
|
|
1303
1322
|
`;
|
|
1323
|
+
const EvaluateActionsDocument = gql`
|
|
1324
|
+
query EvaluateActions(
|
|
1325
|
+
$documentIdentifier: String!
|
|
1326
|
+
$branch: String
|
|
1327
|
+
$candidates: [ActionCandidateInput!]!
|
|
1328
|
+
) {
|
|
1329
|
+
evaluateActions(
|
|
1330
|
+
documentIdentifier: $documentIdentifier
|
|
1331
|
+
branch: $branch
|
|
1332
|
+
candidates: $candidates
|
|
1333
|
+
) {
|
|
1334
|
+
evaluations {
|
|
1335
|
+
decision
|
|
1336
|
+
reason
|
|
1337
|
+
}
|
|
1338
|
+
allAllowed
|
|
1339
|
+
anyAllowed
|
|
1340
|
+
allDenied
|
|
1341
|
+
anyDenied
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
`;
|
|
1304
1345
|
const CreateDocumentDocument = gql`
|
|
1305
1346
|
mutation CreateDocument($document: JSONObject!, $parentIdentifier: String) {
|
|
1306
1347
|
createDocument(document: $document, parentIdentifier: $parentIdentifier) {
|
|
@@ -1509,6 +1550,7 @@ const PollSyncEnvelopesDocument = gql`
|
|
|
1509
1550
|
hash
|
|
1510
1551
|
skip
|
|
1511
1552
|
error
|
|
1553
|
+
deniedReason
|
|
1512
1554
|
id
|
|
1513
1555
|
action {
|
|
1514
1556
|
id
|
|
@@ -1551,6 +1593,7 @@ const PollSyncEnvelopesDocument = gql`
|
|
|
1551
1593
|
deadLetters {
|
|
1552
1594
|
documentId
|
|
1553
1595
|
error
|
|
1596
|
+
errorType
|
|
1554
1597
|
}
|
|
1555
1598
|
hasMore
|
|
1556
1599
|
}
|
|
@@ -1595,6 +1638,9 @@ function getSdk(requester) {
|
|
|
1595
1638
|
GetJobStatus(variables, options) {
|
|
1596
1639
|
return requester(GetJobStatusDocument, variables, options);
|
|
1597
1640
|
},
|
|
1641
|
+
EvaluateActions(variables, options) {
|
|
1642
|
+
return requester(EvaluateActionsDocument, variables, options);
|
|
1643
|
+
},
|
|
1598
1644
|
CreateDocument(variables, options) {
|
|
1599
1645
|
return requester(CreateDocumentDocument, variables, options);
|
|
1600
1646
|
},
|
|
@@ -1745,6 +1791,20 @@ function toReactorPropagationMode(gqlMode) {
|
|
|
1745
1791
|
}
|
|
1746
1792
|
}
|
|
1747
1793
|
/**
|
|
1794
|
+
* Maps one predicted verdict to its GraphQL shape. A refusal's reason is the
|
|
1795
|
+
* consensus string the reactor would record for it, carried through verbatim so
|
|
1796
|
+
* a client can tell a deletion refusal from a missing grant; an allow has none.
|
|
1797
|
+
*/
|
|
1798
|
+
function toGqlActionEvaluation(evaluation) {
|
|
1799
|
+
return evaluation.decision === "allow" ? {
|
|
1800
|
+
decision: AuthDecision.Allow,
|
|
1801
|
+
reason: null
|
|
1802
|
+
} : {
|
|
1803
|
+
decision: AuthDecision.Deny,
|
|
1804
|
+
reason: evaluation.reason
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1748
1808
|
* Converts readonly arrays to mutable arrays for ReactorClient
|
|
1749
1809
|
*/
|
|
1750
1810
|
function toMutableArray(arr) {
|
|
@@ -1904,9 +1964,10 @@ async function documentModels(reactorClient, args) {
|
|
|
1904
1964
|
throw new GraphQLError(`Failed to convert document models to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1905
1965
|
}
|
|
1906
1966
|
}
|
|
1907
|
-
async function document(reactorClient, args) {
|
|
1908
|
-
let view;
|
|
1967
|
+
async function document(reactorClient, args, subject) {
|
|
1968
|
+
let view = subject ? { subject } : void 0;
|
|
1909
1969
|
if (args.view) view = {
|
|
1970
|
+
subject,
|
|
1910
1971
|
branch: fromInputMaybe(args.view.branch),
|
|
1911
1972
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1912
1973
|
};
|
|
@@ -1931,9 +1992,10 @@ async function document(reactorClient, args) {
|
|
|
1931
1992
|
throw new GraphQLError(`Failed to convert document to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1932
1993
|
}
|
|
1933
1994
|
}
|
|
1934
|
-
async function documentOutgoingRelationships(reactorClient, args) {
|
|
1935
|
-
let view;
|
|
1995
|
+
async function documentOutgoingRelationships(reactorClient, args, subject) {
|
|
1996
|
+
let view = subject ? { subject } : void 0;
|
|
1936
1997
|
if (args.view) view = {
|
|
1998
|
+
subject,
|
|
1937
1999
|
branch: fromInputMaybe(args.view.branch),
|
|
1938
2000
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1939
2001
|
};
|
|
@@ -1958,9 +2020,10 @@ async function documentOutgoingRelationships(reactorClient, args) {
|
|
|
1958
2020
|
throw new GraphQLError(`Failed to convert outgoing relationships to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1959
2021
|
}
|
|
1960
2022
|
}
|
|
1961
|
-
async function documentIncomingRelationships(reactorClient, args) {
|
|
1962
|
-
let view;
|
|
2023
|
+
async function documentIncomingRelationships(reactorClient, args, subject) {
|
|
2024
|
+
let view = subject ? { subject } : void 0;
|
|
1963
2025
|
if (args.view) view = {
|
|
2026
|
+
subject,
|
|
1964
2027
|
branch: fromInputMaybe(args.view.branch),
|
|
1965
2028
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1966
2029
|
};
|
|
@@ -1985,9 +2048,10 @@ async function documentIncomingRelationships(reactorClient, args) {
|
|
|
1985
2048
|
throw new GraphQLError(`Failed to convert incoming relationships to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1986
2049
|
}
|
|
1987
2050
|
}
|
|
1988
|
-
async function findDocuments(reactorClient, args) {
|
|
1989
|
-
let view;
|
|
2051
|
+
async function findDocuments(reactorClient, args, subject) {
|
|
2052
|
+
let view = subject ? { subject } : void 0;
|
|
1990
2053
|
if (args.view) view = {
|
|
2054
|
+
subject,
|
|
1991
2055
|
branch: fromInputMaybe(args.view.branch),
|
|
1992
2056
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1993
2057
|
};
|
|
@@ -2029,11 +2093,12 @@ async function jobStatus(reactorClient, args) {
|
|
|
2029
2093
|
throw new GraphQLError(`Failed to convert job status to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2030
2094
|
}
|
|
2031
2095
|
}
|
|
2032
|
-
async function documentOperations(reactorClient, args) {
|
|
2033
|
-
let view;
|
|
2096
|
+
async function documentOperations(reactorClient, args, subject) {
|
|
2097
|
+
let view = subject ? { subject } : void 0;
|
|
2034
2098
|
const branch = fromInputMaybe(args.filter.branch);
|
|
2035
2099
|
const scopes = toMutableArray(fromInputMaybe(args.filter.scopes));
|
|
2036
2100
|
if (branch || scopes) view = {
|
|
2101
|
+
subject,
|
|
2037
2102
|
branch,
|
|
2038
2103
|
scopes
|
|
2039
2104
|
};
|
|
@@ -2069,6 +2134,41 @@ async function documentOperations(reactorClient, args) {
|
|
|
2069
2134
|
throw new GraphQLError(`Failed to convert operations to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2070
2135
|
}
|
|
2071
2136
|
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Predicts the admission verdict for each candidate operation, deciding against
|
|
2139
|
+
* the document policy through the reactor's own decision model.
|
|
2140
|
+
*
|
|
2141
|
+
* The subject is supplied by the subgraph from the authenticated request, never
|
|
2142
|
+
* by the caller: answering for an arbitrary subject would disclose what a policy
|
|
2143
|
+
* grants somebody else. It carries the caller's address and the app key their
|
|
2144
|
+
* token authenticated with, which is the same pair a signed action presents, so
|
|
2145
|
+
* a grant naming either matches here exactly as it would at admission.
|
|
2146
|
+
*
|
|
2147
|
+
* A reactor without authEnforcement raises the named error, which becomes an
|
|
2148
|
+
* "unsupported" code rather than a denial.
|
|
2149
|
+
*/
|
|
2150
|
+
async function evaluateActions(reactorClient, args, subject) {
|
|
2151
|
+
const branch = fromInputMaybe(args.branch) ?? "main";
|
|
2152
|
+
const candidates = args.candidates.map((candidate) => ({
|
|
2153
|
+
scope: candidate.scope,
|
|
2154
|
+
type: candidate.type,
|
|
2155
|
+
input: fromInputMaybe(candidate.input)
|
|
2156
|
+
}));
|
|
2157
|
+
let result;
|
|
2158
|
+
try {
|
|
2159
|
+
result = await reactorClient.evaluateActions(args.documentIdentifier, branch, candidates, subject);
|
|
2160
|
+
} catch (error) {
|
|
2161
|
+
if (AuthEnforcementDisabledError.isError(error)) throw new AuthEvaluationUnsupportedError();
|
|
2162
|
+
throw new GraphQLError(`Failed to evaluate actions: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2163
|
+
}
|
|
2164
|
+
return {
|
|
2165
|
+
evaluations: result.evaluations.map(toGqlActionEvaluation),
|
|
2166
|
+
allAllowed: result.allAllowed,
|
|
2167
|
+
anyAllowed: result.anyAllowed,
|
|
2168
|
+
allDenied: result.allDenied,
|
|
2169
|
+
anyDenied: result.anyDenied
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2072
2172
|
async function createDocument(reactorClient, args, reactorDriveClient) {
|
|
2073
2173
|
if (!args.document || typeof args.document !== "object") throw new GraphQLError("Invalid document: must be an object");
|
|
2074
2174
|
const document = args.document;
|
|
@@ -2347,6 +2447,7 @@ function pollSyncEnvelopes(syncManager, args, forbiddenIds = /* @__PURE__ */ new
|
|
|
2347
2447
|
const deadLetters = remote.channel.deadLetter.items.filter((syncOp) => !forbiddenIds.has(syncOp.documentId)).map((syncOp) => ({
|
|
2348
2448
|
documentId: syncOp.documentId,
|
|
2349
2449
|
error: syncOp.error?.message ?? "Unknown error",
|
|
2450
|
+
errorType: syncOperationErrorType(syncOp.error),
|
|
2350
2451
|
jobId: syncOp.jobId,
|
|
2351
2452
|
branch: syncOp.branch,
|
|
2352
2453
|
scopes: syncOp.scopes,
|
|
@@ -3536,6 +3637,17 @@ const DocumentChangeEventDTO = z.object({
|
|
|
3536
3637
|
documents: z.array(PHDocumentDTO),
|
|
3537
3638
|
context: DocumentChangeContextDTO.nullable().optional()
|
|
3538
3639
|
}).strip();
|
|
3640
|
+
const ActionEvaluationDTO = z.object({
|
|
3641
|
+
decision: z.enum(["ALLOW", "DENY"]),
|
|
3642
|
+
reason: z.string().nullable().optional()
|
|
3643
|
+
}).strip();
|
|
3644
|
+
const ActionEvaluationsDTO = z.object({
|
|
3645
|
+
evaluations: z.array(ActionEvaluationDTO),
|
|
3646
|
+
allAllowed: z.boolean(),
|
|
3647
|
+
anyAllowed: z.boolean(),
|
|
3648
|
+
allDenied: z.boolean(),
|
|
3649
|
+
anyDenied: z.boolean()
|
|
3650
|
+
}).strip();
|
|
3539
3651
|
const JobChangeEventDTO = z.object({
|
|
3540
3652
|
jobId: z.string(),
|
|
3541
3653
|
status: z.string(),
|
|
@@ -3569,6 +3681,9 @@ const operationValidators = {
|
|
|
3569
3681
|
GetJobStatus: (data) => {
|
|
3570
3682
|
if (data.jobStatus) JobInfoDTO.parse(data.jobStatus);
|
|
3571
3683
|
},
|
|
3684
|
+
EvaluateActions: (data) => {
|
|
3685
|
+
if (data.evaluateActions) ActionEvaluationsDTO.parse(data.evaluateActions);
|
|
3686
|
+
},
|
|
3572
3687
|
CreateDocument: (data) => {
|
|
3573
3688
|
if (data.createDocument) PHDocumentDTO.parse(data.createDocument);
|
|
3574
3689
|
},
|
|
@@ -3631,7 +3746,7 @@ function createReactorGraphQLClient(url, fetchImpl = fetch, headers) {
|
|
|
3631
3746
|
}
|
|
3632
3747
|
//#endregion
|
|
3633
3748
|
//#region src/graphql/reactor/schema.graphql
|
|
3634
|
-
var schema_default = "# Scalar types (for codegen - also defined in create-schema.ts)\nscalar JSONObject\nscalar DateTime\n\n# Input types\ninput PagingInput {\n limit: Int\n offset: Int\n cursor: String\n}\n\ninput ViewFilterInput {\n branch: String\n scopes: [String!]\n}\n\ninput SearchFilterInput {\n type: String\n parentId: String\n identifiers: [String!]\n}\n\ninput OperationsFilterInput {\n documentId: String!\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\ninput DocumentOperationsFilterInput {\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\n# Enums\nenum PropagationMode {\n CASCADE\n ORPHAN\n}\n\nenum DocumentChangeType {\n CREATED\n DELETED\n UPDATED\n PARENT_ADDED\n PARENT_REMOVED\n CHILD_ADDED\n CHILD_REMOVED\n}\n\n# Object types\ntype DocumentModelGlobalState {\n id: String!\n name: String!\n namespace: String\n version: String\n specification: JSONObject!\n}\n\ntype DocumentModelResultPage {\n items: [DocumentModelGlobalState!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype Revision {\n scope: String!\n revision: Int!\n}\n\ntype PHDocument {\n id: String!\n slug: String\n preferredEditor: String\n name: String!\n documentType: String!\n state: JSONObject!\n revisionsList: [Revision!]!\n createdAtUtcIso: DateTime!\n lastModifiedAtUtcIso: DateTime!\n operations(\n filter: DocumentOperationsFilterInput\n paging: PagingInput\n ): ReactorOperationResultPage\n}\n\ntype PHDocumentResultPage {\n items: [PHDocument!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype ReactorOperationResultPage {\n items: [ReactorOperation!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype DeadLetterInfo {\n documentId: String!\n error: String!\n jobId: String!\n branch: String!\n scopes: [String!]!\n operationCount: Int!\n}\n\ntype PollSyncEnvelopesResult {\n envelopes: [SyncEnvelope!]!\n ackOrdinal: Int!\n deadLetters: [DeadLetterInfo!]!\n hasMore: Boolean!\n}\n\ntype DocumentWithChildren {\n document: PHDocument!\n childIds: [String!]!\n}\n\ntype MoveRelationshipResult {\n source: PHDocument!\n target: PHDocument!\n}\n\ntype JobInfo {\n id: String!\n status: String!\n result: JSONObject!\n error: String\n createdAt: DateTime!\n completedAt: DateTime\n}\n\ntype DocumentChangeEvent {\n type: DocumentChangeType!\n documents: [PHDocument!]!\n context: DocumentChangeContext\n}\n\ntype DocumentChangeContext {\n parentId: String\n childId: String\n}\n\ntype JobChangeEvent {\n jobId: String!\n status: String!\n result: JSONObject!\n error: String\n}\n\ntype ReactorSignerUser {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ntype ReactorSignerApp {\n name: String!\n key: String!\n}\n\ntype ReactorSigner {\n user: ReactorSignerUser\n app: ReactorSignerApp\n signatures: [String!]!\n}\n\ntype ActionContext {\n signer: ReactorSigner\n}\n\ntype Action {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContext\n}\n\n# Input types for sync operations\ninput ActionContextInput {\n signer: ReactorSignerInput\n}\n\ninput ReactorSignerInput {\n user: ReactorSignerUserInput\n app: ReactorSignerAppInput\n signatures: [String!]!\n}\n\ninput ReactorSignerUserInput {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ninput ReactorSignerAppInput {\n name: String!\n key: String!\n}\n\ninput ActionInput {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContextInput\n}\n\n# Synchronization types\ntype ReactorOperation {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n id: String\n action: Action!\n}\n\ninput OperationInput {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n id: String\n action: ActionInput!\n}\n\ntype OperationContext {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ninput OperationContextInput {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ntype OperationWithContext {\n operation: ReactorOperation!\n context: OperationContext!\n}\n\ninput OperationWithContextInput {\n operation: OperationInput!\n context: OperationContextInput!\n}\n\ntype ChannelMeta {\n id: String!\n}\n\ninput ChannelMetaInput {\n id: String!\n}\n\ntype RemoteCursor {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\ninput RemoteCursorInput {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\nenum SyncEnvelopeType {\n OPERATIONS\n ACK\n}\n\ntype SyncEnvelope {\n type: SyncEnvelopeType!\n channelMeta: ChannelMeta!\n operations: [OperationWithContext!]\n cursor: RemoteCursor\n key: String\n dependsOn: [String!]\n}\n\ninput SyncEnvelopeInput {\n type: SyncEnvelopeType!\n channelMeta: ChannelMetaInput!\n operations: [OperationWithContextInput!]\n cursor: RemoteCursorInput\n key: String\n dependsOn: [String!]\n}\n\ninput RemoteFilterInput {\n documentId: [String!]!\n scope: [String!]!\n branch: String!\n}\n\ninput TouchChannelInput {\n id: String!\n name: String!\n collectionId: String!\n filter: RemoteFilterInput!\n sinceTimestampUtcMs: String!\n}\n\ntype TouchChannelResult {\n success: Boolean!\n ackOrdinal: Int!\n}\n\ntype Query {\n # Get document models for a namespace\n documentModels(\n namespace: String\n paging: PagingInput\n ): DocumentModelResultPage!\n\n # Get a specific document by ID or slug\n document(identifier: String!, view: ViewFilterInput): DocumentWithChildren\n\n # Get outgoing relationships of a given type from a source document\n documentOutgoingRelationships(\n sourceIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get incoming relationships of a given type to a target document\n documentIncomingRelationships(\n targetIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Find documents by search criteria\n findDocuments(\n search: SearchFilterInput\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get job status\n jobStatus(jobId: String!): JobInfo\n\n # Get operations for a document with filtering and pagination\n documentOperations(\n filter: OperationsFilterInput!\n paging: PagingInput\n ): ReactorOperationResultPage!\n\n # Poll for sync envelopes from a channel\n pollSyncEnvelopes(\n channelId: String!\n outboxAck: Int!\n outboxLatest: Int!\n ): PollSyncEnvelopesResult!\n}\n\ntype Mutation {\n # Create a new document\n createDocument(document: JSONObject!, parentIdentifier: String): PHDocument!\n\n # Create an empty document of specified type\n createEmptyDocument(\n documentType: String!\n parentIdentifier: String\n ): PHDocument!\n\n # Apply actions to a document (synchronous)\n mutateDocument(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): PHDocument!\n\n # Submit actions to a document (asynchronous)\n mutateDocumentAsync(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): String!\n\n # Rename a document\n renameDocument(\n documentIdentifier: String!\n name: String!\n branch: String\n ): PHDocument!\n\n # Update the preferred editor recorded in the document header meta.\n # Pass null/omit to clear it.\n setPreferredEditor(\n documentIdentifier: String!\n preferredEditor: String\n branch: String\n ): PHDocument!\n\n # Add a relationship between two documents\n addRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Remove a relationship between two documents\n removeRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Move a relationship from one source to another\n moveRelationship(\n sourceParentIdentifier: String!\n targetParentIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): MoveRelationshipResult!\n\n # Delete a single document\n deleteDocument(identifier: String!, propagate: PropagationMode): Boolean!\n\n # Delete multiple documents\n deleteDocuments(identifiers: [String!]!, propagate: PropagationMode): Boolean!\n\n # Touch (create or update) a channel for sync\n touchChannel(input: TouchChannelInput!): TouchChannelResult!\n\n # Push sync envelopes to a channel\n pushSyncEnvelopes(envelopes: [SyncEnvelopeInput!]!): Boolean!\n}\n\ntype Subscription {\n # Subscribe to document changes\n documentChanges(\n search: SearchFilterInput\n view: ViewFilterInput\n ): DocumentChangeEvent!\n\n # Subscribe to job changes\n jobChanges(jobId: String!): JobChangeEvent!\n}\n";
|
|
3749
|
+
var schema_default = "# Scalar types (for codegen - also defined in create-schema.ts)\nscalar JSONObject\nscalar DateTime\n\n# Input types\ninput PagingInput {\n limit: Int\n offset: Int\n cursor: String\n}\n\ninput ViewFilterInput {\n branch: String\n scopes: [String!]\n}\n\ninput SearchFilterInput {\n type: String\n parentId: String\n identifiers: [String!]\n}\n\ninput OperationsFilterInput {\n documentId: String!\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\ninput DocumentOperationsFilterInput {\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\n# Enums\nenum PropagationMode {\n CASCADE\n ORPHAN\n}\n\nenum DocumentChangeType {\n CREATED\n DELETED\n UPDATED\n PARENT_ADDED\n PARENT_REMOVED\n CHILD_ADDED\n CHILD_REMOVED\n}\n\n# Object types\ntype DocumentModelGlobalState {\n id: String!\n name: String!\n namespace: String\n version: String\n specification: JSONObject!\n}\n\ntype DocumentModelResultPage {\n items: [DocumentModelGlobalState!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype Revision {\n scope: String!\n revision: Int!\n}\n\ntype PHDocument {\n id: String!\n slug: String\n preferredEditor: String\n name: String!\n documentType: String!\n state: JSONObject!\n revisionsList: [Revision!]!\n createdAtUtcIso: DateTime!\n lastModifiedAtUtcIso: DateTime!\n operations(\n filter: DocumentOperationsFilterInput\n paging: PagingInput\n ): ReactorOperationResultPage\n}\n\ntype PHDocumentResultPage {\n items: [PHDocument!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype ReactorOperationResultPage {\n items: [ReactorOperation!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype DeadLetterInfo {\n documentId: String!\n error: String!\n \"\"\"\n How the origin classified the failure. A peer needs this to mirror the origin's\n quarantine decision; without it a held auth operation would freeze the document\n on the peer side while the origin kept syncing.\n \"\"\"\n errorType: String\n jobId: String!\n branch: String!\n scopes: [String!]!\n operationCount: Int!\n}\n\ntype PollSyncEnvelopesResult {\n envelopes: [SyncEnvelope!]!\n ackOrdinal: Int!\n deadLetters: [DeadLetterInfo!]!\n hasMore: Boolean!\n}\n\ntype DocumentWithChildren {\n document: PHDocument!\n childIds: [String!]!\n}\n\ntype MoveRelationshipResult {\n source: PHDocument!\n target: PHDocument!\n}\n\ntype JobInfo {\n id: String!\n status: String!\n result: JSONObject!\n error: String\n createdAt: DateTime!\n completedAt: DateTime\n}\n\ntype DocumentChangeEvent {\n type: DocumentChangeType!\n documents: [PHDocument!]!\n context: DocumentChangeContext\n}\n\ntype DocumentChangeContext {\n parentId: String\n childId: String\n}\n\ntype JobChangeEvent {\n jobId: String!\n status: String!\n result: JSONObject!\n error: String\n}\n\ntype ReactorSignerUser {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ntype ReactorSignerApp {\n name: String!\n key: String!\n}\n\ntype ReactorSigner {\n user: ReactorSignerUser\n app: ReactorSignerApp\n signatures: [String!]!\n}\n\ntype ActionContext {\n signer: ReactorSigner\n}\n\ntype Action {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContext\n}\n\n\"\"\"\nOne operation an authorization preflight predicts a verdict for.\n\n`input` is what a conditional grant reads, so a candidate standing for a\nfilled-in form carries that form's input. Omitting it predicts the verdict an\nempty input earns, not the verdict the filled-in form will get.\n\"\"\"\ninput ActionCandidateInput {\n scope: String!\n type: String!\n input: JSONObject\n}\n\nenum AuthDecision {\n ALLOW\n DENY\n}\n\n\"\"\"\nOne candidate's predicted verdict. `reason` carries the refusal a DENY is\nrecorded with, and is null on an ALLOW.\n\"\"\"\ntype ActionEvaluation {\n decision: AuthDecision!\n reason: String\n}\n\n\"\"\"\nThe predicted verdicts for a set of candidates, in the order they were given,\nwith the aggregates a caller branches on.\n\nThe aggregates are redundant -- a verdict is binary -- and all four are returned\nso a caller reads the one its question is phrased in rather than negating\nanother. Over no candidates every aggregate is false: nothing is allowed and\nnothing is denied.\n\"\"\"\ntype ActionEvaluations {\n evaluations: [ActionEvaluation!]!\n allAllowed: Boolean!\n anyAllowed: Boolean!\n allDenied: Boolean!\n anyDenied: Boolean!\n}\n\n# Input types for sync operations\ninput ActionContextInput {\n signer: ReactorSignerInput\n}\n\ninput ReactorSignerInput {\n user: ReactorSignerUserInput\n app: ReactorSignerAppInput\n signatures: [String!]!\n}\n\ninput ReactorSignerUserInput {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ninput ReactorSignerAppInput {\n name: String!\n key: String!\n}\n\ninput ActionInput {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContextInput\n}\n\n# Synchronization types\ntype ReactorOperation {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n deniedReason: String\n id: String\n action: Action!\n}\n\ninput OperationInput {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n deniedReason: String\n id: String\n action: ActionInput!\n}\n\ntype OperationContext {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ninput OperationContextInput {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ntype OperationWithContext {\n operation: ReactorOperation!\n context: OperationContext!\n}\n\ninput OperationWithContextInput {\n operation: OperationInput!\n context: OperationContextInput!\n}\n\ntype ChannelMeta {\n id: String!\n}\n\ninput ChannelMetaInput {\n id: String!\n}\n\ntype RemoteCursor {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\ninput RemoteCursorInput {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\nenum SyncEnvelopeType {\n OPERATIONS\n ACK\n}\n\ntype SyncEnvelope {\n type: SyncEnvelopeType!\n channelMeta: ChannelMeta!\n operations: [OperationWithContext!]\n cursor: RemoteCursor\n key: String\n dependsOn: [String!]\n}\n\ninput SyncEnvelopeInput {\n type: SyncEnvelopeType!\n channelMeta: ChannelMetaInput!\n operations: [OperationWithContextInput!]\n cursor: RemoteCursorInput\n key: String\n dependsOn: [String!]\n}\n\ninput RemoteFilterInput {\n documentId: [String!]!\n scope: [String!]!\n branch: String!\n}\n\ninput TouchChannelInput {\n id: String!\n name: String!\n collectionId: String!\n filter: RemoteFilterInput!\n sinceTimestampUtcMs: String!\n}\n\ntype TouchChannelResult {\n success: Boolean!\n ackOrdinal: Int!\n}\n\ntype Query {\n # Get document models for a namespace\n documentModels(\n namespace: String\n paging: PagingInput\n ): DocumentModelResultPage!\n\n # Get a specific document by ID or slug\n document(identifier: String!, view: ViewFilterInput): DocumentWithChildren\n\n # Get outgoing relationships of a given type from a source document\n documentOutgoingRelationships(\n sourceIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get incoming relationships of a given type to a target document\n documentIncomingRelationships(\n targetIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Find documents by search criteria\n findDocuments(\n search: SearchFilterInput\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get job status\n jobStatus(jobId: String!): JobInfo\n\n # Get operations for a document with filtering and pagination\n documentOperations(\n filter: OperationsFilterInput!\n paging: PagingInput\n ): ReactorOperationResultPage!\n\n \"\"\"\n Predicts whether the calling subject would be admitted to execute each of a\n set of candidate operations, without submitting any of them. A UI asks this to\n disable a control rather than offer an action that fails on submit.\n\n The answer is a prediction, not a promise:\n\n - Real admission compiles an append condition over everything it read and the\n store enforces it at write time. A preflight reads no future, so a policy\n change landing between this answer and the submit changes the verdict. The\n submit path stays the only authority.\n - The verdict is evaluated at the stream heads, so it is correct for a\n candidate about to be submitted. A backdated submission is out of contract;\n the reactor decides that one by position.\n - A candidate whose verdict depends on its input has to carry that input, since\n a conditional grant reads it.\n\n The subject is the authenticated caller and cannot be named in the request:\n answering for an arbitrary subject would disclose what a policy grants\n somebody else. It carries both the caller's address and the did:key of the app\n instance whose token authenticated the request, so a policy naming either\n matches the same principal the write path presents.\n\n Requires the reactor's authEnforcement feature flag. Without it the reactor\n holds no decision model, so this fails with extensions.code\n AUTH_EVALUATION_UNSUPPORTED rather than guessing.\n \"\"\"\n evaluateActions(\n documentIdentifier: String!\n branch: String\n candidates: [ActionCandidateInput!]!\n ): ActionEvaluations!\n\n # Poll for sync envelopes from a channel\n pollSyncEnvelopes(\n channelId: String!\n outboxAck: Int!\n outboxLatest: Int!\n ): PollSyncEnvelopesResult!\n}\n\ntype Mutation {\n # Create a new document\n createDocument(document: JSONObject!, parentIdentifier: String): PHDocument!\n\n # Create an empty document of specified type\n createEmptyDocument(\n documentType: String!\n parentIdentifier: String\n ): PHDocument!\n\n # Apply actions to a document (synchronous)\n mutateDocument(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): PHDocument!\n\n # Submit actions to a document (asynchronous)\n mutateDocumentAsync(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): String!\n\n # Rename a document\n renameDocument(\n documentIdentifier: String!\n name: String!\n branch: String\n ): PHDocument!\n\n # Update the preferred editor recorded in the document header meta.\n # Pass null/omit to clear it.\n setPreferredEditor(\n documentIdentifier: String!\n preferredEditor: String\n branch: String\n ): PHDocument!\n\n # Add a relationship between two documents\n addRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Remove a relationship between two documents\n removeRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Move a relationship from one source to another\n moveRelationship(\n sourceParentIdentifier: String!\n targetParentIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): MoveRelationshipResult!\n\n # Delete a single document\n deleteDocument(identifier: String!, propagate: PropagationMode): Boolean!\n\n # Delete multiple documents\n deleteDocuments(identifiers: [String!]!, propagate: PropagationMode): Boolean!\n\n # Touch (create or update) a channel for sync\n touchChannel(input: TouchChannelInput!): TouchChannelResult!\n\n # Push sync envelopes to a channel\n pushSyncEnvelopes(envelopes: [SyncEnvelopeInput!]!): Boolean!\n}\n\ntype Subscription {\n # Subscribe to document changes\n documentChanges(\n search: SearchFilterInput\n view: ViewFilterInput\n ): DocumentChangeEvent!\n\n # Subscribe to job changes\n jobChanges(jobId: String!): JobChangeEvent!\n}\n";
|
|
3635
3750
|
//#endregion
|
|
3636
3751
|
//#region src/graphql/reactor/pubsub.ts
|
|
3637
3752
|
const pubSub = new PubSub();
|
|
@@ -3787,7 +3902,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3787
3902
|
return await documentOperations(this.reactorClient, {
|
|
3788
3903
|
filter,
|
|
3789
3904
|
paging: args.paging
|
|
3790
|
-
});
|
|
3905
|
+
}, this.viewSubject(ctx));
|
|
3791
3906
|
} catch (error) {
|
|
3792
3907
|
this.logger.error("Error in PHDocument.operations: @Error", error);
|
|
3793
3908
|
throw error;
|
|
@@ -3810,7 +3925,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3810
3925
|
return await document(this.reactorClient, {
|
|
3811
3926
|
...args,
|
|
3812
3927
|
identifier: handle.fetchIdentifier
|
|
3813
|
-
});
|
|
3928
|
+
}, this.viewSubject(ctx));
|
|
3814
3929
|
} catch (error) {
|
|
3815
3930
|
this.logger.error("Error in document: @Error", error);
|
|
3816
3931
|
throw error;
|
|
@@ -3823,7 +3938,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3823
3938
|
return await documentOutgoingRelationships(this.reactorClient, {
|
|
3824
3939
|
...args,
|
|
3825
3940
|
sourceIdentifier: handle.fetchIdentifier
|
|
3826
|
-
});
|
|
3941
|
+
}, this.viewSubject(ctx));
|
|
3827
3942
|
} catch (error) {
|
|
3828
3943
|
this.logger.error("Error in documentOutgoingRelationships: @Error", error);
|
|
3829
3944
|
throw error;
|
|
@@ -3836,7 +3951,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3836
3951
|
const result = await documentIncomingRelationships(this.reactorClient, {
|
|
3837
3952
|
...args,
|
|
3838
3953
|
targetIdentifier: handle.fetchIdentifier
|
|
3839
|
-
});
|
|
3954
|
+
}, this.viewSubject(ctx));
|
|
3840
3955
|
if (!this.authorizationService.isSupremeAdmin(ctx.user?.address)) {
|
|
3841
3956
|
const filteredItems = [];
|
|
3842
3957
|
for (const item of result.items) if (await this.canReadDocument(item.id, ctx)) filteredItems.push(item);
|
|
@@ -3857,7 +3972,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3857
3972
|
const result = await findDocuments(this.reactorClient, {
|
|
3858
3973
|
...args,
|
|
3859
3974
|
search: args.search ?? {}
|
|
3860
|
-
});
|
|
3975
|
+
}, this.viewSubject(ctx));
|
|
3861
3976
|
if (!this.authorizationService.isSupremeAdmin(ctx.user?.address)) {
|
|
3862
3977
|
const filteredItems = [];
|
|
3863
3978
|
for (const item of result.items) if (await this.canReadDocument(item.id, ctx)) filteredItems.push(item);
|
|
@@ -3891,12 +4006,25 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3891
4006
|
...args.filter,
|
|
3892
4007
|
documentId: handle.fetchIdentifier
|
|
3893
4008
|
}
|
|
3894
|
-
});
|
|
4009
|
+
}, this.viewSubject(ctx));
|
|
3895
4010
|
} catch (error) {
|
|
3896
4011
|
this.logger.error("Error in documentOperations: @Error", error);
|
|
3897
4012
|
throw error;
|
|
3898
4013
|
}
|
|
3899
4014
|
},
|
|
4015
|
+
evaluateActions: async (_parent, args, ctx) => {
|
|
4016
|
+
this.logger.debug("evaluateActions(@args)", args);
|
|
4017
|
+
try {
|
|
4018
|
+
const handle = await this.assertCanRead(args.documentIdentifier, ctx);
|
|
4019
|
+
return await evaluateActions(this.reactorClient, {
|
|
4020
|
+
...args,
|
|
4021
|
+
documentIdentifier: handle.fetchIdentifier
|
|
4022
|
+
}, this.viewSubject(ctx));
|
|
4023
|
+
} catch (error) {
|
|
4024
|
+
this.logger.error("Error in evaluateActions: @Error", error);
|
|
4025
|
+
throw error;
|
|
4026
|
+
}
|
|
4027
|
+
},
|
|
3900
4028
|
pollSyncEnvelopes: async (_parent, args, ctx) => {
|
|
3901
4029
|
this.logger.debug("pollSyncEnvelopes(@args)", args);
|
|
3902
4030
|
try {
|
|
@@ -4205,10 +4333,10 @@ const ADMIN_USERS = getAdminUsers();
|
|
|
4205
4333
|
//#endregion
|
|
4206
4334
|
//#region src/graphql/system/version.ts
|
|
4207
4335
|
function getVersion() {
|
|
4208
|
-
return "6.2.2-dev.
|
|
4336
|
+
return "6.2.2-dev.51";
|
|
4209
4337
|
}
|
|
4210
4338
|
function getGitHash() {
|
|
4211
|
-
return "
|
|
4339
|
+
return "e1c387c6abfd3750231ee194f945b058c07d0002";
|
|
4212
4340
|
}
|
|
4213
4341
|
function getGitUrl() {
|
|
4214
4342
|
return buildTreeUrl(getGitHash());
|
|
@@ -4306,6 +4434,13 @@ var HttpPackageLoader = class {
|
|
|
4306
4434
|
this.logger.verbose(`Loaded ${models.length} document models from ${packageName}`);
|
|
4307
4435
|
return models;
|
|
4308
4436
|
}
|
|
4437
|
+
async loadUpgradeManifests(packageSpec) {
|
|
4438
|
+
const { name: packageName } = this.parsePackageSpec(packageSpec);
|
|
4439
|
+
if (!this.isValidPackageName(packageName)) throw new Error(`Invalid package name: ${packageName}`);
|
|
4440
|
+
const manifests = extractUpgradeManifests(await import(`${this.registryUrl}-/cdn/${packageSpec}/node/document-models/index.mjs`));
|
|
4441
|
+
if (manifests.length > 0) this.logger.verbose(`Loaded ${manifests.length} upgrade manifests from ${packageName}`);
|
|
4442
|
+
return manifests;
|
|
4443
|
+
}
|
|
4309
4444
|
async loadSubgraphs(packageSpec) {
|
|
4310
4445
|
const { name: packageName } = this.parsePackageSpec(packageSpec);
|
|
4311
4446
|
if (!this.isValidPackageName(packageName)) throw new Error(`Invalid package name: ${packageName}`);
|
|
@@ -4431,7 +4566,7 @@ var ImportPackageLoader = class {
|
|
|
4431
4566
|
this.logger.verbose(`Loading document models from package: ${identifier}`);
|
|
4432
4567
|
const pkgModule = await loadDocumentModels(identifier);
|
|
4433
4568
|
if (pkgModule) {
|
|
4434
|
-
const models = Object.values(pkgModule);
|
|
4569
|
+
const models = Object.values(pkgModule).filter((m) => m !== null && typeof m === "object" && "documentModel" in m);
|
|
4435
4570
|
this.logger.verbose(` ➜ Loaded ${models.length} Document Models from: ${identifier}`);
|
|
4436
4571
|
return models;
|
|
4437
4572
|
} else {
|
|
@@ -4439,6 +4574,13 @@ var ImportPackageLoader = class {
|
|
|
4439
4574
|
return [];
|
|
4440
4575
|
}
|
|
4441
4576
|
}
|
|
4577
|
+
async loadUpgradeManifests(identifier) {
|
|
4578
|
+
const pkgModule = await loadDocumentModels(identifier);
|
|
4579
|
+
if (!pkgModule) return [];
|
|
4580
|
+
const manifests = extractUpgradeManifests(pkgModule);
|
|
4581
|
+
if (manifests.length > 0) this.logger.verbose(` ➜ Loaded ${manifests.length} Upgrade Manifests from: ${identifier}`);
|
|
4582
|
+
return manifests;
|
|
4583
|
+
}
|
|
4442
4584
|
async loadSubgraphs(identifier) {
|
|
4443
4585
|
this.logger.verbose(`Loading subgraphs from package: ${identifier}`);
|
|
4444
4586
|
const pkgModule = await loadSubgraphs(identifier);
|
|
@@ -4487,13 +4629,19 @@ function isExpectedLoaderMiss(error, pkg) {
|
|
|
4487
4629
|
}
|
|
4488
4630
|
function getUniqueDocumentModels(...documentModels) {
|
|
4489
4631
|
const uniqueModels = /* @__PURE__ */ new Map();
|
|
4490
|
-
for (const models of documentModels) for (const model of models) uniqueModels.set(model.documentModel.global.id
|
|
4632
|
+
for (const models of documentModels) for (const model of models) uniqueModels.set(`${model.documentModel.global.id}@${model.version ?? 1}`, model);
|
|
4491
4633
|
return Array.from(uniqueModels.values());
|
|
4492
4634
|
}
|
|
4635
|
+
function getUniqueUpgradeManifests(...upgradeManifests) {
|
|
4636
|
+
const uniqueManifests = /* @__PURE__ */ new Map();
|
|
4637
|
+
for (const manifests of upgradeManifests) for (const manifest of manifests) uniqueManifests.set(manifest.documentType, manifest);
|
|
4638
|
+
return Array.from(uniqueManifests.values());
|
|
4639
|
+
}
|
|
4493
4640
|
var PackageManager = class {
|
|
4494
4641
|
logger = childLogger(["reactor-api", "package-manager"]);
|
|
4495
4642
|
loaders;
|
|
4496
4643
|
docModelsMap = /* @__PURE__ */ new Map();
|
|
4644
|
+
upgradeManifestsMap = /* @__PURE__ */ new Map();
|
|
4497
4645
|
subgraphsMap = /* @__PURE__ */ new Map();
|
|
4498
4646
|
processorMap = /* @__PURE__ */ new Map();
|
|
4499
4647
|
configWatcher;
|
|
@@ -4511,8 +4659,10 @@ var PackageManager = class {
|
|
|
4511
4659
|
async loadPackages(packages) {
|
|
4512
4660
|
this.logger.info("Loading packages: @packages", packages.join(", "));
|
|
4513
4661
|
const documentModelsMap = await this.loadDocumentModels(packages);
|
|
4662
|
+
const upgradeManifestsMap = await this.loadUpgradeManifests(packages);
|
|
4514
4663
|
const subgraphsMap = await this.loadSubgraphs(packages);
|
|
4515
4664
|
const processorsMap = await this.loadProcessors(packages);
|
|
4665
|
+
this.upgradeManifestsMap = upgradeManifestsMap;
|
|
4516
4666
|
this.updatePackagesMap(documentModelsMap);
|
|
4517
4667
|
this.updateSubgraphsMap(subgraphsMap);
|
|
4518
4668
|
this.updateProcessorsMap(processorsMap);
|
|
@@ -4523,6 +4673,7 @@ var PackageManager = class {
|
|
|
4523
4673
|
}
|
|
4524
4674
|
return {
|
|
4525
4675
|
documentModels: getUniqueDocumentModels(...Array.from(documentModelsMap.values())),
|
|
4676
|
+
upgradeManifests: this.getUniqueUpgradeManifests(),
|
|
4526
4677
|
subgraphs: subgraphsMap,
|
|
4527
4678
|
processors: processorsMap
|
|
4528
4679
|
};
|
|
@@ -4533,6 +4684,7 @@ var PackageManager = class {
|
|
|
4533
4684
|
documentModelModuleMap.set("document-drive", [driveDocumentModelModule]);
|
|
4534
4685
|
documentModelModuleMap.set("document-model", [documentModelDocumentModelModule]);
|
|
4535
4686
|
documentModelModuleMap.set("reactor-drive", [reactorDriveDocumentModelModule]);
|
|
4687
|
+
documentModelModuleMap.set("reactor-group", [ReactorGroupV1]);
|
|
4536
4688
|
for (const pkg of packages) {
|
|
4537
4689
|
const allDocumentModels = [];
|
|
4538
4690
|
const failures = [];
|
|
@@ -4555,6 +4707,26 @@ var PackageManager = class {
|
|
|
4555
4707
|
}
|
|
4556
4708
|
return documentModelModuleMap;
|
|
4557
4709
|
}
|
|
4710
|
+
/** Upgrade manifests currently loaded across all packages, one per type. */
|
|
4711
|
+
getUniqueUpgradeManifests() {
|
|
4712
|
+
return getUniqueUpgradeManifests(...Array.from(this.upgradeManifestsMap.values()));
|
|
4713
|
+
}
|
|
4714
|
+
async loadUpgradeManifests(packages) {
|
|
4715
|
+
const manifestsMap = /* @__PURE__ */ new Map();
|
|
4716
|
+
for (const pkg of packages) for (const loader of this.loaders) {
|
|
4717
|
+
if (!loader.loadUpgradeManifests) continue;
|
|
4718
|
+
try {
|
|
4719
|
+
const manifests = await loader.loadUpgradeManifests(pkg);
|
|
4720
|
+
if (manifests.length > 0) {
|
|
4721
|
+
manifestsMap.set(pkg, manifests);
|
|
4722
|
+
break;
|
|
4723
|
+
}
|
|
4724
|
+
} catch (error) {
|
|
4725
|
+
this.logger.debug(`[${loader.name}] Failed to load upgrade manifests from package @pkg: @error`, pkg, error);
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
return manifestsMap;
|
|
4729
|
+
}
|
|
4558
4730
|
async loadSubgraphs(packages) {
|
|
4559
4731
|
this.logger.debug(`Loading subgraphs from packages: ${packages.join(", ")}`);
|
|
4560
4732
|
const subgraphsMap = /* @__PURE__ */ new Map();
|
|
@@ -4616,6 +4788,10 @@ var PackageManager = class {
|
|
|
4616
4788
|
async updateDocumentModelsForPackage(pkg) {
|
|
4617
4789
|
this.logger.debug(`Updating document models for package: ${pkg}`);
|
|
4618
4790
|
const documentModels = await this.loadDocumentModels([pkg]);
|
|
4791
|
+
const upgradeManifests = await this.loadUpgradeManifests([pkg]);
|
|
4792
|
+
const upgradeManifestsMap = new Map(this.upgradeManifestsMap);
|
|
4793
|
+
upgradeManifestsMap.set(pkg, upgradeManifests.get(pkg) ?? []);
|
|
4794
|
+
this.upgradeManifestsMap = upgradeManifestsMap;
|
|
4619
4795
|
const documentModelsMap = new Map(this.docModelsMap);
|
|
4620
4796
|
documentModelsMap.set(pkg, documentModels.get(pkg) ?? []);
|
|
4621
4797
|
this.updatePackagesMap(documentModelsMap);
|
|
@@ -4695,6 +4871,70 @@ var PackageManager = class {
|
|
|
4695
4871
|
const config = { basePath: process.env.BASE_PATH || "/" };
|
|
4696
4872
|
const DefaultCoreSubgraphs = [AnalyticsSubgraph, SystemSubgraph];
|
|
4697
4873
|
//#endregion
|
|
4874
|
+
//#region src/attachment-backend.ts
|
|
4875
|
+
/** Filesystem is the default; explicit S3 is readiness-gated without fallback. */
|
|
4876
|
+
async function createStartupAttachmentBackend({ db, env = process.env, s3Dependencies }) {
|
|
4877
|
+
const storage = parseAttachmentStorageConfig(env);
|
|
4878
|
+
if (storage.kind === "filesystem") return void 0;
|
|
4879
|
+
const backend = createS3AttachmentBackend(db.withSchema("attachments"), storage.s3, s3Dependencies);
|
|
4880
|
+
if (!(await backend.health()).ready) throw new Error("S3 attachment backend readiness check failed");
|
|
4881
|
+
return backend;
|
|
4882
|
+
}
|
|
4883
|
+
//#endregion
|
|
4884
|
+
//#region src/services/attachment-access.service.ts
|
|
4885
|
+
const HASH_PATTERN = /^[a-f0-9]{64}$/;
|
|
4886
|
+
/**
|
|
4887
|
+
* Composes document authorization with the projected document/ref
|
|
4888
|
+
* relationship. Order is fixed: validate ref, resolve the canonical document
|
|
4889
|
+
* id, check `canRead`, then check the reference index. A denied document
|
|
4890
|
+
* never reaches the reference reader, and the facade never touches
|
|
4891
|
+
* attachment metadata, storage backends, or presigners.
|
|
4892
|
+
*/
|
|
4893
|
+
var AttachmentAccessService = class {
|
|
4894
|
+
constructor(resolveCanonicalId, authorization, references, projection) {
|
|
4895
|
+
this.resolveCanonicalId = resolveCanonicalId;
|
|
4896
|
+
this.authorization = authorization;
|
|
4897
|
+
this.references = references;
|
|
4898
|
+
this.projection = projection;
|
|
4899
|
+
}
|
|
4900
|
+
async canReadAttachment(request) {
|
|
4901
|
+
if (this.projection.status !== "available") return { kind: "projection-unavailable" };
|
|
4902
|
+
const ref = normalizeAttachmentRef(request.attachmentRef);
|
|
4903
|
+
if (ref === null) return { kind: "denied" };
|
|
4904
|
+
let documentId;
|
|
4905
|
+
try {
|
|
4906
|
+
documentId = await this.resolveCanonicalId(request.documentId);
|
|
4907
|
+
} catch {
|
|
4908
|
+
return { kind: "denied" };
|
|
4909
|
+
}
|
|
4910
|
+
if (!await this.authorization.canRead(documentId, request.userAddress)) return { kind: "denied" };
|
|
4911
|
+
if (!await this.references.hasReference(documentId, ref)) return { kind: "denied" };
|
|
4912
|
+
return {
|
|
4913
|
+
kind: "allowed",
|
|
4914
|
+
documentId,
|
|
4915
|
+
ref
|
|
4916
|
+
};
|
|
4917
|
+
}
|
|
4918
|
+
};
|
|
4919
|
+
/**
|
|
4920
|
+
* Parses and canonicalizes a caller-supplied ref through the shared parser.
|
|
4921
|
+
* Returns null for anything that is not a v1 ref over a 64-char SHA-256 hex
|
|
4922
|
+
* hash; hex case is normalized so index lookups use the canonical form.
|
|
4923
|
+
*/
|
|
4924
|
+
function normalizeAttachmentRef(value) {
|
|
4925
|
+
let hash;
|
|
4926
|
+
let version;
|
|
4927
|
+
try {
|
|
4928
|
+
const parsed = parseRef(value);
|
|
4929
|
+
hash = parsed.hash.toLowerCase();
|
|
4930
|
+
version = parsed.version;
|
|
4931
|
+
} catch {
|
|
4932
|
+
return null;
|
|
4933
|
+
}
|
|
4934
|
+
if (version !== 1 || !HASH_PATTERN.test(hash)) return null;
|
|
4935
|
+
return createRef(hash, version);
|
|
4936
|
+
}
|
|
4937
|
+
//#endregion
|
|
4698
4938
|
//#region src/migrations/001_create_document_permissions.ts
|
|
4699
4939
|
var _001_create_document_permissions_exports = /* @__PURE__ */ __exportAll({
|
|
4700
4940
|
down: () => down$2,
|
|
@@ -4921,8 +5161,7 @@ var AuthService = class {
|
|
|
4921
5161
|
admins: [],
|
|
4922
5162
|
auth_enabled: false
|
|
4923
5163
|
};
|
|
4924
|
-
|
|
4925
|
-
if (method === "OPTIONS" || method === "GET") return {
|
|
5164
|
+
if (request.method === "OPTIONS") return {
|
|
4926
5165
|
user: void 0,
|
|
4927
5166
|
admins: this.config.admins,
|
|
4928
5167
|
auth_enabled: true
|
|
@@ -4984,16 +5223,23 @@ var AuthService = class {
|
|
|
4984
5223
|
return await verifyAuthBearerToken(token);
|
|
4985
5224
|
}
|
|
4986
5225
|
/**
|
|
4987
|
-
* Extract user information from verification result
|
|
5226
|
+
* Extract user information from verification result.
|
|
5227
|
+
*
|
|
5228
|
+
* The issuer is required along with the credential subject. A credential that
|
|
5229
|
+
* verified must carry one -- resolving it is how the signature was checked --
|
|
5230
|
+
* so this rejects a shape that cannot have come from verification rather than
|
|
5231
|
+
* admitting a keyless principal.
|
|
4988
5232
|
*/
|
|
4989
5233
|
extractUserFromVerification(verified) {
|
|
4990
5234
|
try {
|
|
4991
5235
|
const { address, chainId, networkId } = verified.verifiableCredential.credentialSubject;
|
|
4992
|
-
|
|
5236
|
+
const appKey = verified.issuer;
|
|
5237
|
+
if (!address || !chainId || !networkId || !appKey) return null;
|
|
4993
5238
|
return {
|
|
4994
5239
|
address,
|
|
4995
5240
|
chainId,
|
|
4996
|
-
networkId
|
|
5241
|
+
networkId,
|
|
5242
|
+
appKey
|
|
4997
5243
|
};
|
|
4998
5244
|
} catch {
|
|
4999
5245
|
return null;
|
|
@@ -5042,14 +5288,33 @@ var AuthService = class {
|
|
|
5042
5288
|
}
|
|
5043
5289
|
}
|
|
5044
5290
|
async fetchCredentialExists(address, chainId, appId) {
|
|
5045
|
-
|
|
5291
|
+
if (!this.config.verifyCredential) throw new Error("AuthService: credential verification is enabled but no verifyCredential was provided");
|
|
5292
|
+
return this.config.verifyCredential({
|
|
5046
5293
|
address,
|
|
5047
5294
|
chainId,
|
|
5048
|
-
|
|
5049
|
-
})
|
|
5295
|
+
appId
|
|
5296
|
+
});
|
|
5050
5297
|
}
|
|
5051
5298
|
};
|
|
5052
5299
|
//#endregion
|
|
5300
|
+
//#region src/services/renown-credential-verifier.ts
|
|
5301
|
+
async function createRenownCredentialVerifier(config = {}) {
|
|
5302
|
+
const switchboardUrl = await resolveSwitchboardEndpoint({
|
|
5303
|
+
switchboardUrl: config.switchboardUrl,
|
|
5304
|
+
baseUrl: config.renownUrl
|
|
5305
|
+
});
|
|
5306
|
+
return async ({ address, chainId, appId }) => {
|
|
5307
|
+
return await fetchDelegationCredential({
|
|
5308
|
+
address,
|
|
5309
|
+
chainId,
|
|
5310
|
+
appDid: appId,
|
|
5311
|
+
switchboardUrl,
|
|
5312
|
+
baseUrl: switchboardUrl ? void 0 : config.renownUrl,
|
|
5313
|
+
discover: false
|
|
5314
|
+
}) !== void 0;
|
|
5315
|
+
};
|
|
5316
|
+
}
|
|
5317
|
+
//#endregion
|
|
5053
5318
|
//#region src/services/document-permission.service.ts
|
|
5054
5319
|
/**
|
|
5055
5320
|
* Service for managing document-level permissions.
|
|
@@ -5568,15 +5833,20 @@ async function setupGraphQLManager(httpAdapter, authFetchMiddleware, httpServer,
|
|
|
5568
5833
|
function setupEventListeners(pkgManager, graphqlManager, reactorProcessorManager, module, documentModelRegistry) {
|
|
5569
5834
|
pkgManager.onDocumentModelsChange((packagedModels) => {
|
|
5570
5835
|
if (documentModelRegistry) {
|
|
5571
|
-
const newModules = Object.values(packagedModels).flat();
|
|
5572
|
-
const
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
const results
|
|
5577
|
-
for (const result of results) if (result.status === "success") defaultLogger.info(`Registered new document model: ${result.item.documentModel.global.id}`);
|
|
5836
|
+
const newModules = getUniqueDocumentModels(Object.values(packagedModels).flat());
|
|
5837
|
+
const incomingTypes = new Set(newModules.map((m) => m.documentModel.global.id));
|
|
5838
|
+
if (incomingTypes.size > 0) {
|
|
5839
|
+
documentModelRegistry.unregisterModules(...incomingTypes);
|
|
5840
|
+
const results = documentModelRegistry.registerModules(...newModules);
|
|
5841
|
+
for (const result of results) if (result.status === "success") defaultLogger.info(`Registered document model: ${result.item.documentModel.global.id} v${result.item.version ?? 1}`);
|
|
5578
5842
|
else defaultLogger.error(`Failed to register document model: ${result.error.message}`);
|
|
5579
5843
|
}
|
|
5844
|
+
const manifests = pkgManager.getUniqueUpgradeManifests();
|
|
5845
|
+
if (manifests.length > 0) {
|
|
5846
|
+
documentModelRegistry.unregisterUpgradeManifests(...manifests.map((m) => m.documentType));
|
|
5847
|
+
const manifestResults = documentModelRegistry.registerUpgradeManifests(...manifests);
|
|
5848
|
+
for (const result of manifestResults) if (result.status === "error") defaultLogger.error(`Failed to register upgrade manifest: ${result.error.message}`);
|
|
5849
|
+
}
|
|
5580
5850
|
}
|
|
5581
5851
|
graphqlManager.regenerateDocumentModelSubgraphs();
|
|
5582
5852
|
});
|
|
@@ -5641,7 +5911,7 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5641
5911
|
admins = options.auth.admins.map((a) => a.toLowerCase());
|
|
5642
5912
|
authEnabled = options.auth.enabled;
|
|
5643
5913
|
}
|
|
5644
|
-
const { AUTH_ENABLED, ADMINS, DEFAULT_PROTECTION, DOCUMENT_PERMISSIONS_ENABLED, SKIP_CREDENTIAL_VERIFICATION, CREDENTIAL_VERIFICATION_CACHE_TTL_MS } = process.env;
|
|
5914
|
+
const { AUTH_ENABLED, ADMINS, DEFAULT_PROTECTION, DOCUMENT_PERMISSIONS_ENABLED, SKIP_CREDENTIAL_VERIFICATION, CREDENTIAL_VERIFICATION_CACHE_TTL_MS, RENOWN_URL, SWITCHBOARD_URL } = process.env;
|
|
5645
5915
|
if (AUTH_ENABLED !== void 0) authEnabled = AUTH_ENABLED === "true";
|
|
5646
5916
|
if (ADMINS !== void 0) admins = ADMINS.split(",").map((a) => a.toLowerCase());
|
|
5647
5917
|
let defaultProtection = false;
|
|
@@ -5677,7 +5947,11 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5677
5947
|
enabled: authEnabled,
|
|
5678
5948
|
admins,
|
|
5679
5949
|
skipCredentialVerification,
|
|
5680
|
-
credentialVerificationCacheTtlMs
|
|
5950
|
+
credentialVerificationCacheTtlMs,
|
|
5951
|
+
verifyCredential: await createRenownCredentialVerifier({
|
|
5952
|
+
renownUrl: RENOWN_URL,
|
|
5953
|
+
switchboardUrl: SWITCHBOARD_URL
|
|
5954
|
+
})
|
|
5681
5955
|
});
|
|
5682
5956
|
authFetchMiddleware = createAuthFetchMiddleware(authService);
|
|
5683
5957
|
}
|
|
@@ -5703,7 +5977,12 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5703
5977
|
await mkdir(attachmentStoragePath, { recursive: true });
|
|
5704
5978
|
const { db: attachmentDb, knex: attachmentKnex, pglite: attachmentPglite } = getDbClient(options.dbPath, options.pgliteFactory);
|
|
5705
5979
|
dbClosers.push(...makeDbClosers(attachmentKnex, attachmentPglite));
|
|
5706
|
-
const
|
|
5980
|
+
const ATTACHMENT_SWEEP_INTERVAL_MS = 3600 * 1e3;
|
|
5981
|
+
const attachmentBackend = await createStartupAttachmentBackend({ db: attachmentDb });
|
|
5982
|
+
const attachmentBuilder = new AttachmentBuilder(attachmentDb, attachmentStoragePath).withReservationSweepMs(ATTACHMENT_SWEEP_INTERVAL_MS);
|
|
5983
|
+
if (attachmentBackend) attachmentBuilder.withBackend(attachmentBackend);
|
|
5984
|
+
const attachments = await attachmentBuilder.build();
|
|
5985
|
+
const attachmentReferenceIndex = await new AttachmentReferenceIndexBuilder(attachmentDb).build();
|
|
5707
5986
|
dbClosers.push(() => {
|
|
5708
5987
|
attachments.destroy();
|
|
5709
5988
|
return Promise.resolve();
|
|
@@ -5723,6 +6002,7 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5723
6002
|
documentPermissionService,
|
|
5724
6003
|
authorizationConfig,
|
|
5725
6004
|
attachments,
|
|
6005
|
+
attachmentReferenceIndex,
|
|
5726
6006
|
packages,
|
|
5727
6007
|
dbClosers,
|
|
5728
6008
|
readiness
|
|
@@ -5731,7 +6011,7 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5731
6011
|
/**
|
|
5732
6012
|
* Private helper function containing common setup logic for API initialization
|
|
5733
6013
|
*/
|
|
5734
|
-
async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, readModels, attachments, authorizationConfig, documentModelRegistry, dbClosers = [], reactorDriveClient) {
|
|
6014
|
+
async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, readModels, attachments, attachmentReferenceIndex, attachmentReferenceProjection, authorizationConfig, documentModelRegistry, dbClosers = [], reactorDriveClient) {
|
|
5735
6015
|
const hostModule = {
|
|
5736
6016
|
relationalDb,
|
|
5737
6017
|
analyticsStore,
|
|
@@ -5778,6 +6058,7 @@ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, ht
|
|
|
5778
6058
|
const { httpServer, wsServer } = await startServer(httpAdapter, port, options.https, logger);
|
|
5779
6059
|
const authorizationService = createAuthorizationService(authorizationConfig, documentPermissionService, createGetParentIdsFn(reactorClient));
|
|
5780
6060
|
logger.info(`Authorization service initialized (policy: ${authorizationConfig.policy})`);
|
|
6061
|
+
const attachmentAccess = new AttachmentAccessService(createCanonicalDocumentIdResolver(reactorClient), authorizationService, attachmentReferenceIndex.store, attachmentReferenceProjection);
|
|
5781
6062
|
const coreSubgraphs = DefaultCoreSubgraphs.slice();
|
|
5782
6063
|
coreSubgraphs.push(ReactorSubgraph);
|
|
5783
6064
|
if (documentPermissionService) {
|
|
@@ -5802,6 +6083,8 @@ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, ht
|
|
|
5802
6083
|
graphqlManager,
|
|
5803
6084
|
packages,
|
|
5804
6085
|
attachments,
|
|
6086
|
+
attachmentReferenceIndex,
|
|
6087
|
+
attachmentAccess,
|
|
5805
6088
|
authService,
|
|
5806
6089
|
dispose: buildApiDispose({
|
|
5807
6090
|
graphqlManager,
|
|
@@ -5850,9 +6133,15 @@ function buildApiDispose(args) {
|
|
|
5850
6133
|
};
|
|
5851
6134
|
}
|
|
5852
6135
|
async function initializeAndStartAPI(clientInitializer, options, processorApp) {
|
|
5853
|
-
const { port, httpAdapter, authFetchMiddleware, authService, relationalDb, analyticsStore, documentPermissionService, authorizationConfig, attachments, packages, dbClosers, readiness } = await _setupCommonInfrastructure(options);
|
|
5854
|
-
const { documentModels, processors, subgraphs } = await packages.init();
|
|
5855
|
-
const { module: reactorClientModule, reactorDriveClient
|
|
6136
|
+
const { port, httpAdapter, authFetchMiddleware, authService, relationalDb, analyticsStore, documentPermissionService, authorizationConfig, attachments, attachmentReferenceIndex, packages, dbClosers, readiness } = await _setupCommonInfrastructure(options);
|
|
6137
|
+
const { documentModels, upgradeManifests, processors, subgraphs } = await packages.init();
|
|
6138
|
+
const { module: reactorClientModule, reactorDriveClient, attachmentReferenceProjection = {
|
|
6139
|
+
status: "unavailable",
|
|
6140
|
+
reason: "initializer-did-not-report"
|
|
6141
|
+
} } = await clientInitializer(documentModels, {
|
|
6142
|
+
attachmentReferenceWriter: attachmentReferenceIndex.store,
|
|
6143
|
+
upgradeManifests
|
|
6144
|
+
});
|
|
5856
6145
|
const reactorClient = reactorClientModule.client;
|
|
5857
6146
|
const syncManager = reactorClientModule.reactorModule?.syncModule?.syncManager;
|
|
5858
6147
|
if (!syncManager) throw new Error("SyncManager not available from InProcessReactorClientModule");
|
|
@@ -5861,11 +6150,12 @@ async function initializeAndStartAPI(clientInitializer, options, processorApp) {
|
|
|
5861
6150
|
const documentModelRegistry = reactorClientModule.reactorModule?.documentModelRegistry;
|
|
5862
6151
|
if (!documentModelRegistry) throw new Error("DocumentModelRegistry not available from InProcessReactorClientModule");
|
|
5863
6152
|
return {
|
|
5864
|
-
...await _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, (reactorClientModule.reactorModule?.readModelCoordinator)?.readModels ?? [], attachments, authorizationConfig, documentModelRegistry, dbClosers, reactorDriveClient),
|
|
6153
|
+
...await _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, (reactorClientModule.reactorModule?.readModelCoordinator)?.readModels ?? [], attachments, attachmentReferenceIndex, attachmentReferenceProjection, authorizationConfig, documentModelRegistry, dbClosers, reactorDriveClient),
|
|
5865
6154
|
client: reactorClient,
|
|
5866
6155
|
syncManager,
|
|
5867
6156
|
documentModelRegistry,
|
|
5868
|
-
readiness
|
|
6157
|
+
readiness,
|
|
6158
|
+
attachmentReferenceProjection
|
|
5869
6159
|
};
|
|
5870
6160
|
}
|
|
5871
6161
|
//#endregion
|
|
@@ -5969,7 +6259,7 @@ var PackageManagementService = class {
|
|
|
5969
6259
|
}
|
|
5970
6260
|
};
|
|
5971
6261
|
//#endregion
|
|
5972
|
-
export { ADMIN_USERS, ActionContextInputSchema, ActionInputSchema, AddRelationshipDocument, AnalyticsSubgraph, AuthService, AuthSubgraph, AuthorizationPolicy, AuthorizedDocumentHandle, BaseSubgraph, ChannelMetaInputSchema, CreateDocumentDocument, CreateEmptyDocumentDocument, DeleteDocumentDocument, DeleteDocumentsDocument, DocumentChangeType, DocumentChangeTypeSchema, DocumentChangesDocument, DocumentOperationsFilterInputSchema, DocumentPermissionService, FindDocumentsDocument, GetDocumentDocument, GetDocumentIncomingRelationshipsDocument, GetDocumentModelsDocument, GetDocumentOperationsDocument, GetDocumentOutgoingRelationshipsDocument, GetDocumentWithOperationsDocument, GetJobStatusDocument, GraphQLManager, HttpDocumentModelLoader, HttpPackageLoader, ImportPackageLoader, InMemoryPackageStorage, JobChangesDocument, MoveRelationshipDocument, MutateDocumentAsyncDocument, MutateDocumentDocument, OperationContextInputSchema, OperationInputSchema, OperationWithContextInputSchema, OperationsFilterInputSchema, PackageManagementService, PackageManager, PackagesSubgraph, PagingInputSchema, PhDocumentFieldsFragmentDoc, PollSyncEnvelopesDocument, PropagationMode, PropagationModeSchema, PushSyncEnvelopesDocument, ReactorSignerAppInputSchema, ReactorSignerInputSchema, ReactorSignerUserInputSchema, ReactorSubgraph, RemoteCursorInputSchema, RemoteFilterInputSchema, RemoveRelationshipDocument, RenameDocumentDocument, SearchFilterInputSchema, SetPreferredEditorDocument, SyncEnvelopeInputSchema, SyncEnvelopeType, SyncEnvelopeTypeSchema, SystemSubgraph, TouchChannelDocument, TouchChannelInputSchema, ViewFilterInputSchema, assertAuthRequiredForDocumentPermissions, assertSkipCredentialVerificationAllowed, buildGraphQlDocument, buildGraphQlDriveDocument, buildGraphqlOperation, buildGraphqlOperations, buildSubgraphSchemaModule, createAuthFetchMiddleware, createGatewayAdapter, createHttpAdapter, createMergedSchema, createReactorGraphQLClient, createSchema, definedNonNullAnySchema, driveIdFromUrl, extractSubgraphsFromModule, generateDocumentModelSchema, getAuthContext, getDbClient, getDocumentModelSchemaName, getDocumentModelTypeDefs, getGitHash, getGitUrl, getSdk, getUniqueDocumentModels, getVersion, initAnalyticsStoreSql, initializeAndStartAPI, isDefinedNonNullAny, isExpectedLoaderMiss, isSubgraphClass, parseDriveUrl, renderGraphqlPlayground };
|
|
6262
|
+
export { ADMIN_USERS, ActionCandidateInputSchema, ActionContextInputSchema, ActionInputSchema, AddRelationshipDocument, AnalyticsSubgraph, AttachmentAccessService, AuthDecision, AuthDecisionSchema, AuthService, AuthSubgraph, AuthorizationPolicy, AuthorizedDocumentHandle, BaseSubgraph, CanonicalDocumentIdResolutionError, ChannelMetaInputSchema, CreateDocumentDocument, CreateEmptyDocumentDocument, DeleteDocumentDocument, DeleteDocumentsDocument, DocumentChangeType, DocumentChangeTypeSchema, DocumentChangesDocument, DocumentOperationsFilterInputSchema, DocumentPermissionService, EvaluateActionsDocument, FindDocumentsDocument, GetDocumentDocument, GetDocumentIncomingRelationshipsDocument, GetDocumentModelsDocument, GetDocumentOperationsDocument, GetDocumentOutgoingRelationshipsDocument, GetDocumentWithOperationsDocument, GetJobStatusDocument, GraphQLManager, HttpDocumentModelLoader, HttpPackageLoader, ImportPackageLoader, InMemoryPackageStorage, JobChangesDocument, MoveRelationshipDocument, MutateDocumentAsyncDocument, MutateDocumentDocument, OperationContextInputSchema, OperationInputSchema, OperationWithContextInputSchema, OperationsFilterInputSchema, PackageManagementService, PackageManager, PackagesSubgraph, PagingInputSchema, PhDocumentFieldsFragmentDoc, PollSyncEnvelopesDocument, PropagationMode, PropagationModeSchema, PushSyncEnvelopesDocument, ReactorSignerAppInputSchema, ReactorSignerInputSchema, ReactorSignerUserInputSchema, ReactorSubgraph, RemoteCursorInputSchema, RemoteFilterInputSchema, RemoveRelationshipDocument, RenameDocumentDocument, SearchFilterInputSchema, SetPreferredEditorDocument, SyncEnvelopeInputSchema, SyncEnvelopeType, SyncEnvelopeTypeSchema, SystemSubgraph, TouchChannelDocument, TouchChannelInputSchema, ViewFilterInputSchema, assertAuthRequiredForDocumentPermissions, assertSkipCredentialVerificationAllowed, buildGraphQlDocument, buildGraphQlDriveDocument, buildGraphqlOperation, buildGraphqlOperations, buildSubgraphSchemaModule, createAuthFetchMiddleware, createCanonicalDocumentIdResolver, createGatewayAdapter, createHttpAdapter, createMergedSchema, createReactorGraphQLClient, createRenownCredentialVerifier, createSchema, definedNonNullAnySchema, driveIdFromUrl, extractSubgraphsFromModule, generateDocumentModelSchema, getAuthContext, getDbClient, getDocumentModelSchemaName, getDocumentModelTypeDefs, getGitHash, getGitUrl, getSdk, getUniqueDocumentModels, getUniqueUpgradeManifests, getVersion, initAnalyticsStoreSql, initializeAndStartAPI, isDefinedNonNullAny, isExpectedLoaderMiss, isSubgraphClass, parseDriveUrl, renderGraphqlPlayground };
|
|
5973
6263
|
|
|
5974
6264
|
//# sourceMappingURL=index.mjs.map
|
|
5975
|
-
//# debugId=
|
|
6265
|
+
//# debugId=50fb0cae-c1a3-5acc-9be1-417f9b1814c6
|