@powerhousedao/reactor-api 6.2.2-dev.4 → 6.2.2-dev.40
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 +113 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +152 -51
- package/dist/index.mjs.map +1 -1
- package/dist/src/packages/vite-loader.mjs +1 -1
- package/dist/{utils-iibOQ50e.mjs → utils-BdPg2whY.mjs} +41 -7
- package/dist/utils-BdPg2whY.mjs.map +1 -0
- package/package.json +13 -13
- 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, c as loadDocumentModels, d as BaseSubgraph, f as
|
|
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]="f661f924-a48f-516e-8739-859d08b54d00")}catch(e){}}();
|
|
3
|
+
import { a as isSubgraphClass, c as loadDocumentModels, d as BaseSubgraph, f as CanonicalDocumentIdResolutionError, g as createAuthorizationService, h as AuthorizedDocumentHandle, i as buildGraphqlOperations, l as loadProcessors, m as AuthorizationPolicy, n as buildGraphQlDriveDocument, o as debounce, p as createCanonicalDocumentIdResolver, r as buildGraphqlOperation, t as buildGraphQlDocument, u as loadSubgraphs } from "./utils-BdPg2whY.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 { 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";
|
|
@@ -26,7 +26,7 @@ import { driveDocumentModelModule } from "@powerhousedao/shared/document-drive";
|
|
|
26
26
|
import EventEmitter from "node:events";
|
|
27
27
|
import fs, { watchFile } from "node:fs";
|
|
28
28
|
import { PostgresAnalyticsStore } from "@powerhousedao/analytics-engine-pg";
|
|
29
|
-
import { AttachmentBuilder } from "@powerhousedao/reactor-attachments";
|
|
29
|
+
import { AttachmentBuilder, AttachmentReferenceIndexBuilder, createRef, createS3AttachmentBackend, parseAttachmentStorageConfig, parseRef } from "@powerhousedao/reactor-attachments";
|
|
30
30
|
import { createAttachmentClient } from "@powerhousedao/reactor-attachments/client";
|
|
31
31
|
import { setupMcpServer } from "@powerhousedao/reactor-mcp";
|
|
32
32
|
import { mkdir } from "node:fs/promises";
|
|
@@ -34,7 +34,7 @@ import { tmpdir } from "node:os";
|
|
|
34
34
|
import { WebSocketServer } from "ws";
|
|
35
35
|
import { createRelationalDb } from "@powerhousedao/shared/processors";
|
|
36
36
|
import { Kysely, Migrator, sql } from "kysely";
|
|
37
|
-
import { verifyAuthBearerToken } from "@renown/sdk";
|
|
37
|
+
import { fetchDelegationCredential, resolveSwitchboardEndpoint, verifyAuthBearerToken } from "@renown/sdk";
|
|
38
38
|
import { PGlite } from "@electric-sql/pglite";
|
|
39
39
|
import { AtomicNodeFs } from "@powerhousedao/pglite-fs";
|
|
40
40
|
import knex from "knex";
|
|
@@ -460,6 +460,7 @@ const getDocumentModelTypeDefs = (documentModels, typeDefs$1) => {
|
|
|
460
460
|
});
|
|
461
461
|
return dedupeTypeDefinitions(gql`
|
|
462
462
|
scalar JSONObject
|
|
463
|
+
scalar AttachmentRef
|
|
463
464
|
${typeDefs.join("\n").replaceAll(";", "")}
|
|
464
465
|
|
|
465
466
|
type PHOperationContext {
|
|
@@ -878,6 +879,7 @@ function generateNewApiSchema(documentName, specification, _stateSchemaTypes, pr
|
|
|
878
879
|
return gql`
|
|
879
880
|
scalar DateTime
|
|
880
881
|
scalar JSONObject
|
|
882
|
+
scalar AttachmentRef
|
|
881
883
|
|
|
882
884
|
${revisionType}
|
|
883
885
|
|
|
@@ -989,6 +991,7 @@ function OperationContextInputSchema() {
|
|
|
989
991
|
function OperationInputSchema() {
|
|
990
992
|
return z$1.object({
|
|
991
993
|
action: z$1.lazy(() => ActionInputSchema()),
|
|
994
|
+
deniedReason: z$1.string().nullish(),
|
|
992
995
|
error: z$1.string().nullish(),
|
|
993
996
|
hash: z$1.string(),
|
|
994
997
|
id: z$1.string().nullish(),
|
|
@@ -1147,6 +1150,7 @@ const GetDocumentWithOperationsDocument = gql`
|
|
|
1147
1150
|
hash
|
|
1148
1151
|
skip
|
|
1149
1152
|
error
|
|
1153
|
+
deniedReason
|
|
1150
1154
|
id
|
|
1151
1155
|
action {
|
|
1152
1156
|
id
|
|
@@ -1259,6 +1263,7 @@ const GetDocumentOperationsDocument = gql`
|
|
|
1259
1263
|
hash
|
|
1260
1264
|
skip
|
|
1261
1265
|
error
|
|
1266
|
+
deniedReason
|
|
1262
1267
|
id
|
|
1263
1268
|
action {
|
|
1264
1269
|
id
|
|
@@ -1509,6 +1514,7 @@ const PollSyncEnvelopesDocument = gql`
|
|
|
1509
1514
|
hash
|
|
1510
1515
|
skip
|
|
1511
1516
|
error
|
|
1517
|
+
deniedReason
|
|
1512
1518
|
id
|
|
1513
1519
|
action {
|
|
1514
1520
|
id
|
|
@@ -1551,6 +1557,7 @@ const PollSyncEnvelopesDocument = gql`
|
|
|
1551
1557
|
deadLetters {
|
|
1552
1558
|
documentId
|
|
1553
1559
|
error
|
|
1560
|
+
errorType
|
|
1554
1561
|
}
|
|
1555
1562
|
hasMore
|
|
1556
1563
|
}
|
|
@@ -1904,9 +1911,10 @@ async function documentModels(reactorClient, args) {
|
|
|
1904
1911
|
throw new GraphQLError(`Failed to convert document models to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1905
1912
|
}
|
|
1906
1913
|
}
|
|
1907
|
-
async function document(reactorClient, args) {
|
|
1908
|
-
let view;
|
|
1914
|
+
async function document(reactorClient, args, subject) {
|
|
1915
|
+
let view = subject ? { subject } : void 0;
|
|
1909
1916
|
if (args.view) view = {
|
|
1917
|
+
subject,
|
|
1910
1918
|
branch: fromInputMaybe(args.view.branch),
|
|
1911
1919
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1912
1920
|
};
|
|
@@ -1931,9 +1939,10 @@ async function document(reactorClient, args) {
|
|
|
1931
1939
|
throw new GraphQLError(`Failed to convert document to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1932
1940
|
}
|
|
1933
1941
|
}
|
|
1934
|
-
async function documentOutgoingRelationships(reactorClient, args) {
|
|
1935
|
-
let view;
|
|
1942
|
+
async function documentOutgoingRelationships(reactorClient, args, subject) {
|
|
1943
|
+
let view = subject ? { subject } : void 0;
|
|
1936
1944
|
if (args.view) view = {
|
|
1945
|
+
subject,
|
|
1937
1946
|
branch: fromInputMaybe(args.view.branch),
|
|
1938
1947
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1939
1948
|
};
|
|
@@ -1958,9 +1967,10 @@ async function documentOutgoingRelationships(reactorClient, args) {
|
|
|
1958
1967
|
throw new GraphQLError(`Failed to convert outgoing relationships to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1959
1968
|
}
|
|
1960
1969
|
}
|
|
1961
|
-
async function documentIncomingRelationships(reactorClient, args) {
|
|
1962
|
-
let view;
|
|
1970
|
+
async function documentIncomingRelationships(reactorClient, args, subject) {
|
|
1971
|
+
let view = subject ? { subject } : void 0;
|
|
1963
1972
|
if (args.view) view = {
|
|
1973
|
+
subject,
|
|
1964
1974
|
branch: fromInputMaybe(args.view.branch),
|
|
1965
1975
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1966
1976
|
};
|
|
@@ -1985,9 +1995,10 @@ async function documentIncomingRelationships(reactorClient, args) {
|
|
|
1985
1995
|
throw new GraphQLError(`Failed to convert incoming relationships to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1986
1996
|
}
|
|
1987
1997
|
}
|
|
1988
|
-
async function findDocuments(reactorClient, args) {
|
|
1989
|
-
let view;
|
|
1998
|
+
async function findDocuments(reactorClient, args, subject) {
|
|
1999
|
+
let view = subject ? { subject } : void 0;
|
|
1990
2000
|
if (args.view) view = {
|
|
2001
|
+
subject,
|
|
1991
2002
|
branch: fromInputMaybe(args.view.branch),
|
|
1992
2003
|
scopes: toMutableArray(fromInputMaybe(args.view.scopes))
|
|
1993
2004
|
};
|
|
@@ -2029,11 +2040,12 @@ async function jobStatus(reactorClient, args) {
|
|
|
2029
2040
|
throw new GraphQLError(`Failed to convert job status to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2030
2041
|
}
|
|
2031
2042
|
}
|
|
2032
|
-
async function documentOperations(reactorClient, args) {
|
|
2033
|
-
let view;
|
|
2043
|
+
async function documentOperations(reactorClient, args, subject) {
|
|
2044
|
+
let view = subject ? { subject } : void 0;
|
|
2034
2045
|
const branch = fromInputMaybe(args.filter.branch);
|
|
2035
2046
|
const scopes = toMutableArray(fromInputMaybe(args.filter.scopes));
|
|
2036
2047
|
if (branch || scopes) view = {
|
|
2048
|
+
subject,
|
|
2037
2049
|
branch,
|
|
2038
2050
|
scopes
|
|
2039
2051
|
};
|
|
@@ -2347,6 +2359,7 @@ function pollSyncEnvelopes(syncManager, args, forbiddenIds = /* @__PURE__ */ new
|
|
|
2347
2359
|
const deadLetters = remote.channel.deadLetter.items.filter((syncOp) => !forbiddenIds.has(syncOp.documentId)).map((syncOp) => ({
|
|
2348
2360
|
documentId: syncOp.documentId,
|
|
2349
2361
|
error: syncOp.error?.message ?? "Unknown error",
|
|
2362
|
+
errorType: syncOperationErrorType(syncOp.error),
|
|
2350
2363
|
jobId: syncOp.jobId,
|
|
2351
2364
|
branch: syncOp.branch,
|
|
2352
2365
|
scopes: syncOp.scopes,
|
|
@@ -3631,7 +3644,7 @@ function createReactorGraphQLClient(url, fetchImpl = fetch, headers) {
|
|
|
3631
3644
|
}
|
|
3632
3645
|
//#endregion
|
|
3633
3646
|
//#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";
|
|
3647
|
+
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# 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 # 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
3648
|
//#endregion
|
|
3636
3649
|
//#region src/graphql/reactor/pubsub.ts
|
|
3637
3650
|
const pubSub = new PubSub();
|
|
@@ -3787,7 +3800,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3787
3800
|
return await documentOperations(this.reactorClient, {
|
|
3788
3801
|
filter,
|
|
3789
3802
|
paging: args.paging
|
|
3790
|
-
});
|
|
3803
|
+
}, this.viewSubject(ctx));
|
|
3791
3804
|
} catch (error) {
|
|
3792
3805
|
this.logger.error("Error in PHDocument.operations: @Error", error);
|
|
3793
3806
|
throw error;
|
|
@@ -3810,7 +3823,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3810
3823
|
return await document(this.reactorClient, {
|
|
3811
3824
|
...args,
|
|
3812
3825
|
identifier: handle.fetchIdentifier
|
|
3813
|
-
});
|
|
3826
|
+
}, this.viewSubject(ctx));
|
|
3814
3827
|
} catch (error) {
|
|
3815
3828
|
this.logger.error("Error in document: @Error", error);
|
|
3816
3829
|
throw error;
|
|
@@ -3823,7 +3836,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3823
3836
|
return await documentOutgoingRelationships(this.reactorClient, {
|
|
3824
3837
|
...args,
|
|
3825
3838
|
sourceIdentifier: handle.fetchIdentifier
|
|
3826
|
-
});
|
|
3839
|
+
}, this.viewSubject(ctx));
|
|
3827
3840
|
} catch (error) {
|
|
3828
3841
|
this.logger.error("Error in documentOutgoingRelationships: @Error", error);
|
|
3829
3842
|
throw error;
|
|
@@ -3836,7 +3849,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3836
3849
|
const result = await documentIncomingRelationships(this.reactorClient, {
|
|
3837
3850
|
...args,
|
|
3838
3851
|
targetIdentifier: handle.fetchIdentifier
|
|
3839
|
-
});
|
|
3852
|
+
}, this.viewSubject(ctx));
|
|
3840
3853
|
if (!this.authorizationService.isSupremeAdmin(ctx.user?.address)) {
|
|
3841
3854
|
const filteredItems = [];
|
|
3842
3855
|
for (const item of result.items) if (await this.canReadDocument(item.id, ctx)) filteredItems.push(item);
|
|
@@ -3857,7 +3870,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3857
3870
|
const result = await findDocuments(this.reactorClient, {
|
|
3858
3871
|
...args,
|
|
3859
3872
|
search: args.search ?? {}
|
|
3860
|
-
});
|
|
3873
|
+
}, this.viewSubject(ctx));
|
|
3861
3874
|
if (!this.authorizationService.isSupremeAdmin(ctx.user?.address)) {
|
|
3862
3875
|
const filteredItems = [];
|
|
3863
3876
|
for (const item of result.items) if (await this.canReadDocument(item.id, ctx)) filteredItems.push(item);
|
|
@@ -3891,7 +3904,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
|
|
|
3891
3904
|
...args.filter,
|
|
3892
3905
|
documentId: handle.fetchIdentifier
|
|
3893
3906
|
}
|
|
3894
|
-
});
|
|
3907
|
+
}, this.viewSubject(ctx));
|
|
3895
3908
|
} catch (error) {
|
|
3896
3909
|
this.logger.error("Error in documentOperations: @Error", error);
|
|
3897
3910
|
throw error;
|
|
@@ -4205,10 +4218,10 @@ const ADMIN_USERS = getAdminUsers();
|
|
|
4205
4218
|
//#endregion
|
|
4206
4219
|
//#region src/graphql/system/version.ts
|
|
4207
4220
|
function getVersion() {
|
|
4208
|
-
return "6.2.2-dev.
|
|
4221
|
+
return "6.2.2-dev.40";
|
|
4209
4222
|
}
|
|
4210
4223
|
function getGitHash() {
|
|
4211
|
-
return "
|
|
4224
|
+
return "f8df8612cf5853f4c12c5fe80cab40cfcf23a6de";
|
|
4212
4225
|
}
|
|
4213
4226
|
function getGitUrl() {
|
|
4214
4227
|
return buildTreeUrl(getGitHash());
|
|
@@ -4695,6 +4708,70 @@ var PackageManager = class {
|
|
|
4695
4708
|
const config = { basePath: process.env.BASE_PATH || "/" };
|
|
4696
4709
|
const DefaultCoreSubgraphs = [AnalyticsSubgraph, SystemSubgraph];
|
|
4697
4710
|
//#endregion
|
|
4711
|
+
//#region src/attachment-backend.ts
|
|
4712
|
+
/** Filesystem is the default; explicit S3 is readiness-gated without fallback. */
|
|
4713
|
+
async function createStartupAttachmentBackend({ db, env = process.env, s3Dependencies }) {
|
|
4714
|
+
const storage = parseAttachmentStorageConfig(env);
|
|
4715
|
+
if (storage.kind === "filesystem") return void 0;
|
|
4716
|
+
const backend = createS3AttachmentBackend(db.withSchema("attachments"), storage.s3, s3Dependencies);
|
|
4717
|
+
if (!(await backend.health()).ready) throw new Error("S3 attachment backend readiness check failed");
|
|
4718
|
+
return backend;
|
|
4719
|
+
}
|
|
4720
|
+
//#endregion
|
|
4721
|
+
//#region src/services/attachment-access.service.ts
|
|
4722
|
+
const HASH_PATTERN = /^[a-f0-9]{64}$/;
|
|
4723
|
+
/**
|
|
4724
|
+
* Composes document authorization with the projected document/ref
|
|
4725
|
+
* relationship. Order is fixed: validate ref, resolve the canonical document
|
|
4726
|
+
* id, check `canRead`, then check the reference index. A denied document
|
|
4727
|
+
* never reaches the reference reader, and the facade never touches
|
|
4728
|
+
* attachment metadata, storage backends, or presigners.
|
|
4729
|
+
*/
|
|
4730
|
+
var AttachmentAccessService = class {
|
|
4731
|
+
constructor(resolveCanonicalId, authorization, references, projection) {
|
|
4732
|
+
this.resolveCanonicalId = resolveCanonicalId;
|
|
4733
|
+
this.authorization = authorization;
|
|
4734
|
+
this.references = references;
|
|
4735
|
+
this.projection = projection;
|
|
4736
|
+
}
|
|
4737
|
+
async canReadAttachment(request) {
|
|
4738
|
+
if (this.projection.status !== "available") return { kind: "projection-unavailable" };
|
|
4739
|
+
const ref = normalizeAttachmentRef(request.attachmentRef);
|
|
4740
|
+
if (ref === null) return { kind: "denied" };
|
|
4741
|
+
let documentId;
|
|
4742
|
+
try {
|
|
4743
|
+
documentId = await this.resolveCanonicalId(request.documentId);
|
|
4744
|
+
} catch {
|
|
4745
|
+
return { kind: "denied" };
|
|
4746
|
+
}
|
|
4747
|
+
if (!await this.authorization.canRead(documentId, request.userAddress)) return { kind: "denied" };
|
|
4748
|
+
if (!await this.references.hasReference(documentId, ref)) return { kind: "denied" };
|
|
4749
|
+
return {
|
|
4750
|
+
kind: "allowed",
|
|
4751
|
+
documentId,
|
|
4752
|
+
ref
|
|
4753
|
+
};
|
|
4754
|
+
}
|
|
4755
|
+
};
|
|
4756
|
+
/**
|
|
4757
|
+
* Parses and canonicalizes a caller-supplied ref through the shared parser.
|
|
4758
|
+
* Returns null for anything that is not a v1 ref over a 64-char SHA-256 hex
|
|
4759
|
+
* hash; hex case is normalized so index lookups use the canonical form.
|
|
4760
|
+
*/
|
|
4761
|
+
function normalizeAttachmentRef(value) {
|
|
4762
|
+
let hash;
|
|
4763
|
+
let version;
|
|
4764
|
+
try {
|
|
4765
|
+
const parsed = parseRef(value);
|
|
4766
|
+
hash = parsed.hash.toLowerCase();
|
|
4767
|
+
version = parsed.version;
|
|
4768
|
+
} catch {
|
|
4769
|
+
return null;
|
|
4770
|
+
}
|
|
4771
|
+
if (version !== 1 || !HASH_PATTERN.test(hash)) return null;
|
|
4772
|
+
return createRef(hash, version);
|
|
4773
|
+
}
|
|
4774
|
+
//#endregion
|
|
4698
4775
|
//#region src/migrations/001_create_document_permissions.ts
|
|
4699
4776
|
var _001_create_document_permissions_exports = /* @__PURE__ */ __exportAll({
|
|
4700
4777
|
down: () => down$2,
|
|
@@ -5041,27 +5118,34 @@ var AuthService = class {
|
|
|
5041
5118
|
this.credentialCache.delete(oldestKey);
|
|
5042
5119
|
}
|
|
5043
5120
|
}
|
|
5044
|
-
/**
|
|
5045
|
-
* Fetch the credential from the Renown API and validate it against the
|
|
5046
|
-
* expected address, chainId and issuer. Never throws; returns false on any
|
|
5047
|
-
* network or validation failure.
|
|
5048
|
-
*/
|
|
5049
5121
|
async fetchCredentialExists(address, chainId, appId) {
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
const addressVerfied = credential.issuer.id.split(":")[4];
|
|
5057
|
-
const chainIdVerfied = credential.issuer.id.split(":")[3];
|
|
5058
|
-
return appIdVerfied === appId && addressVerfied.toLocaleLowerCase() === address.toLocaleLowerCase() && chainIdVerfied === chainId.toString();
|
|
5059
|
-
} catch {
|
|
5060
|
-
return false;
|
|
5061
|
-
}
|
|
5122
|
+
if (!this.config.verifyCredential) throw new Error("AuthService: credential verification is enabled but no verifyCredential was provided");
|
|
5123
|
+
return this.config.verifyCredential({
|
|
5124
|
+
address,
|
|
5125
|
+
chainId,
|
|
5126
|
+
appId
|
|
5127
|
+
});
|
|
5062
5128
|
}
|
|
5063
5129
|
};
|
|
5064
5130
|
//#endregion
|
|
5131
|
+
//#region src/services/renown-credential-verifier.ts
|
|
5132
|
+
async function createRenownCredentialVerifier(config = {}) {
|
|
5133
|
+
const switchboardUrl = await resolveSwitchboardEndpoint({
|
|
5134
|
+
switchboardUrl: config.switchboardUrl,
|
|
5135
|
+
baseUrl: config.renownUrl
|
|
5136
|
+
});
|
|
5137
|
+
return async ({ address, chainId, appId }) => {
|
|
5138
|
+
return await fetchDelegationCredential({
|
|
5139
|
+
address,
|
|
5140
|
+
chainId,
|
|
5141
|
+
appDid: appId,
|
|
5142
|
+
switchboardUrl,
|
|
5143
|
+
baseUrl: switchboardUrl ? void 0 : config.renownUrl,
|
|
5144
|
+
discover: false
|
|
5145
|
+
}) !== void 0;
|
|
5146
|
+
};
|
|
5147
|
+
}
|
|
5148
|
+
//#endregion
|
|
5065
5149
|
//#region src/services/document-permission.service.ts
|
|
5066
5150
|
/**
|
|
5067
5151
|
* Service for managing document-level permissions.
|
|
@@ -5653,7 +5737,7 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5653
5737
|
admins = options.auth.admins.map((a) => a.toLowerCase());
|
|
5654
5738
|
authEnabled = options.auth.enabled;
|
|
5655
5739
|
}
|
|
5656
|
-
const { AUTH_ENABLED, ADMINS, DEFAULT_PROTECTION, DOCUMENT_PERMISSIONS_ENABLED, SKIP_CREDENTIAL_VERIFICATION, CREDENTIAL_VERIFICATION_CACHE_TTL_MS } = process.env;
|
|
5740
|
+
const { AUTH_ENABLED, ADMINS, DEFAULT_PROTECTION, DOCUMENT_PERMISSIONS_ENABLED, SKIP_CREDENTIAL_VERIFICATION, CREDENTIAL_VERIFICATION_CACHE_TTL_MS, RENOWN_URL, SWITCHBOARD_URL } = process.env;
|
|
5657
5741
|
if (AUTH_ENABLED !== void 0) authEnabled = AUTH_ENABLED === "true";
|
|
5658
5742
|
if (ADMINS !== void 0) admins = ADMINS.split(",").map((a) => a.toLowerCase());
|
|
5659
5743
|
let defaultProtection = false;
|
|
@@ -5689,7 +5773,11 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5689
5773
|
enabled: authEnabled,
|
|
5690
5774
|
admins,
|
|
5691
5775
|
skipCredentialVerification,
|
|
5692
|
-
credentialVerificationCacheTtlMs
|
|
5776
|
+
credentialVerificationCacheTtlMs,
|
|
5777
|
+
verifyCredential: await createRenownCredentialVerifier({
|
|
5778
|
+
renownUrl: RENOWN_URL,
|
|
5779
|
+
switchboardUrl: SWITCHBOARD_URL
|
|
5780
|
+
})
|
|
5693
5781
|
});
|
|
5694
5782
|
authFetchMiddleware = createAuthFetchMiddleware(authService);
|
|
5695
5783
|
}
|
|
@@ -5715,7 +5803,12 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5715
5803
|
await mkdir(attachmentStoragePath, { recursive: true });
|
|
5716
5804
|
const { db: attachmentDb, knex: attachmentKnex, pglite: attachmentPglite } = getDbClient(options.dbPath, options.pgliteFactory);
|
|
5717
5805
|
dbClosers.push(...makeDbClosers(attachmentKnex, attachmentPglite));
|
|
5718
|
-
const
|
|
5806
|
+
const ATTACHMENT_SWEEP_INTERVAL_MS = 3600 * 1e3;
|
|
5807
|
+
const attachmentBackend = await createStartupAttachmentBackend({ db: attachmentDb });
|
|
5808
|
+
const attachmentBuilder = new AttachmentBuilder(attachmentDb, attachmentStoragePath).withReservationSweepMs(ATTACHMENT_SWEEP_INTERVAL_MS);
|
|
5809
|
+
if (attachmentBackend) attachmentBuilder.withBackend(attachmentBackend);
|
|
5810
|
+
const attachments = await attachmentBuilder.build();
|
|
5811
|
+
const attachmentReferenceIndex = await new AttachmentReferenceIndexBuilder(attachmentDb).build();
|
|
5719
5812
|
dbClosers.push(() => {
|
|
5720
5813
|
attachments.destroy();
|
|
5721
5814
|
return Promise.resolve();
|
|
@@ -5735,6 +5828,7 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5735
5828
|
documentPermissionService,
|
|
5736
5829
|
authorizationConfig,
|
|
5737
5830
|
attachments,
|
|
5831
|
+
attachmentReferenceIndex,
|
|
5738
5832
|
packages,
|
|
5739
5833
|
dbClosers,
|
|
5740
5834
|
readiness
|
|
@@ -5743,7 +5837,7 @@ async function _setupCommonInfrastructure(options) {
|
|
|
5743
5837
|
/**
|
|
5744
5838
|
* Private helper function containing common setup logic for API initialization
|
|
5745
5839
|
*/
|
|
5746
|
-
async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, readModels, attachments, authorizationConfig, documentModelRegistry, dbClosers = [], reactorDriveClient) {
|
|
5840
|
+
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) {
|
|
5747
5841
|
const hostModule = {
|
|
5748
5842
|
relationalDb,
|
|
5749
5843
|
analyticsStore,
|
|
@@ -5790,6 +5884,7 @@ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, ht
|
|
|
5790
5884
|
const { httpServer, wsServer } = await startServer(httpAdapter, port, options.https, logger);
|
|
5791
5885
|
const authorizationService = createAuthorizationService(authorizationConfig, documentPermissionService, createGetParentIdsFn(reactorClient));
|
|
5792
5886
|
logger.info(`Authorization service initialized (policy: ${authorizationConfig.policy})`);
|
|
5887
|
+
const attachmentAccess = new AttachmentAccessService(createCanonicalDocumentIdResolver(reactorClient), authorizationService, attachmentReferenceIndex.store, attachmentReferenceProjection);
|
|
5793
5888
|
const coreSubgraphs = DefaultCoreSubgraphs.slice();
|
|
5794
5889
|
coreSubgraphs.push(ReactorSubgraph);
|
|
5795
5890
|
if (documentPermissionService) {
|
|
@@ -5814,6 +5909,8 @@ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, ht
|
|
|
5814
5909
|
graphqlManager,
|
|
5815
5910
|
packages,
|
|
5816
5911
|
attachments,
|
|
5912
|
+
attachmentReferenceIndex,
|
|
5913
|
+
attachmentAccess,
|
|
5817
5914
|
authService,
|
|
5818
5915
|
dispose: buildApiDispose({
|
|
5819
5916
|
graphqlManager,
|
|
@@ -5862,9 +5959,12 @@ function buildApiDispose(args) {
|
|
|
5862
5959
|
};
|
|
5863
5960
|
}
|
|
5864
5961
|
async function initializeAndStartAPI(clientInitializer, options, processorApp) {
|
|
5865
|
-
const { port, httpAdapter, authFetchMiddleware, authService, relationalDb, analyticsStore, documentPermissionService, authorizationConfig, attachments, packages, dbClosers, readiness } = await _setupCommonInfrastructure(options);
|
|
5962
|
+
const { port, httpAdapter, authFetchMiddleware, authService, relationalDb, analyticsStore, documentPermissionService, authorizationConfig, attachments, attachmentReferenceIndex, packages, dbClosers, readiness } = await _setupCommonInfrastructure(options);
|
|
5866
5963
|
const { documentModels, processors, subgraphs } = await packages.init();
|
|
5867
|
-
const { module: reactorClientModule, reactorDriveClient
|
|
5964
|
+
const { module: reactorClientModule, reactorDriveClient, attachmentReferenceProjection = {
|
|
5965
|
+
status: "unavailable",
|
|
5966
|
+
reason: "initializer-did-not-report"
|
|
5967
|
+
} } = await clientInitializer(documentModels, { attachmentReferenceWriter: attachmentReferenceIndex.store });
|
|
5868
5968
|
const reactorClient = reactorClientModule.client;
|
|
5869
5969
|
const syncManager = reactorClientModule.reactorModule?.syncModule?.syncManager;
|
|
5870
5970
|
if (!syncManager) throw new Error("SyncManager not available from InProcessReactorClientModule");
|
|
@@ -5873,11 +5973,12 @@ async function initializeAndStartAPI(clientInitializer, options, processorApp) {
|
|
|
5873
5973
|
const documentModelRegistry = reactorClientModule.reactorModule?.documentModelRegistry;
|
|
5874
5974
|
if (!documentModelRegistry) throw new Error("DocumentModelRegistry not available from InProcessReactorClientModule");
|
|
5875
5975
|
return {
|
|
5876
|
-
...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),
|
|
5976
|
+
...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),
|
|
5877
5977
|
client: reactorClient,
|
|
5878
5978
|
syncManager,
|
|
5879
5979
|
documentModelRegistry,
|
|
5880
|
-
readiness
|
|
5980
|
+
readiness,
|
|
5981
|
+
attachmentReferenceProjection
|
|
5881
5982
|
};
|
|
5882
5983
|
}
|
|
5883
5984
|
//#endregion
|
|
@@ -5981,7 +6082,7 @@ var PackageManagementService = class {
|
|
|
5981
6082
|
}
|
|
5982
6083
|
};
|
|
5983
6084
|
//#endregion
|
|
5984
|
-
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 };
|
|
6085
|
+
export { ADMIN_USERS, ActionContextInputSchema, ActionInputSchema, AddRelationshipDocument, AnalyticsSubgraph, AttachmentAccessService, AuthService, AuthSubgraph, AuthorizationPolicy, AuthorizedDocumentHandle, BaseSubgraph, CanonicalDocumentIdResolutionError, 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, createCanonicalDocumentIdResolver, createGatewayAdapter, createHttpAdapter, createMergedSchema, createReactorGraphQLClient, createRenownCredentialVerifier, createSchema, definedNonNullAnySchema, driveIdFromUrl, extractSubgraphsFromModule, generateDocumentModelSchema, getAuthContext, getDbClient, getDocumentModelSchemaName, getDocumentModelTypeDefs, getGitHash, getGitUrl, getSdk, getUniqueDocumentModels, getVersion, initAnalyticsStoreSql, initializeAndStartAPI, isDefinedNonNullAny, isExpectedLoaderMiss, isSubgraphClass, parseDriveUrl, renderGraphqlPlayground };
|
|
5985
6086
|
|
|
5986
6087
|
//# sourceMappingURL=index.mjs.map
|
|
5987
|
-
//# debugId=
|
|
6088
|
+
//# debugId=f661f924-a48f-516e-8739-859d08b54d00
|