@powerhousedao/reactor-api 6.2.3-dev.3 → 6.2.3-dev.31
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/README.md +7 -2
- package/dist/{adapter-gateway-apollo-Cn9E96GF.mjs → adapter-gateway-apollo-B54G_cXT.mjs} +18 -17
- package/dist/adapter-gateway-apollo-B54G_cXT.mjs.map +1 -0
- package/dist/{adapter-gateway-apollo-C_RdohOv.mjs → adapter-gateway-apollo-D2DNlPY0.mjs} +3 -3
- package/dist/{adapter-gateway-mercurius-CjaUcMgX.mjs → adapter-gateway-mercurius-rbKlwF9m.mjs} +7 -6
- package/dist/adapter-gateway-mercurius-rbKlwF9m.mjs.map +1 -0
- package/dist/{adapter-gateway-stitching-HmWjRMhm.mjs → adapter-gateway-stitching-Dzv10u8D.mjs} +18 -14
- package/dist/adapter-gateway-stitching-Dzv10u8D.mjs.map +1 -0
- package/dist/{adapter-http-express-B39rPhqH.mjs → adapter-http-express-CWqziB1p.mjs} +7 -7
- package/dist/adapter-http-express-CWqziB1p.mjs.map +1 -0
- package/dist/{adapter-http-fastify-BwXO6rqE.mjs → adapter-http-fastify-CYZQ6FFv.mjs} +10 -9
- package/dist/adapter-http-fastify-CYZQ6FFv.mjs.map +1 -0
- package/dist/index.d.mts +865 -453
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1160 -320
- package/dist/index.mjs.map +1 -1
- package/dist/{utils-XWVecaNn.mjs → pieces-WWMZBM0n.mjs} +146 -9
- package/dist/pieces-WWMZBM0n.mjs.map +1 -0
- package/dist/rolldown-runtime-8H4AJuhK.mjs +16 -0
- package/dist/run-node-handler-CQjyjOuN.mjs +52 -0
- package/dist/run-node-handler-CQjyjOuN.mjs.map +1 -0
- package/dist/src/packages/https-hooks.d.mts +4 -4
- package/dist/src/packages/https-hooks.d.mts.map +1 -1
- package/dist/src/packages/https-hooks.mjs +2 -2
- package/dist/src/packages/https-hooks.mjs.map +1 -1
- package/dist/src/packages/vite-loader.d.mts +10 -6
- package/dist/src/packages/vite-loader.d.mts.map +1 -1
- package/dist/src/packages/vite-loader.mjs +71 -9
- package/dist/src/packages/vite-loader.mjs.map +1 -1
- package/dist/{types-DcYyNcHJ.d.mts → types-CuSz_zv6.d.mts} +26 -3
- package/dist/types-CuSz_zv6.d.mts.map +1 -0
- package/dist/{websocket-DncAB9XK.mjs → websocket-_SH5aBcy.mjs} +3 -3
- package/dist/{websocket-DncAB9XK.mjs.map → websocket-_SH5aBcy.mjs.map} +1 -1
- package/package.json +18 -18
- package/dist/adapter-gateway-apollo-Cn9E96GF.mjs.map +0 -1
- package/dist/adapter-gateway-mercurius-CjaUcMgX.mjs.map +0 -1
- package/dist/adapter-gateway-stitching-HmWjRMhm.mjs.map +0 -1
- package/dist/adapter-http-express-B39rPhqH.mjs.map +0 -1
- package/dist/adapter-http-fastify-BwXO6rqE.mjs.map +0 -1
- package/dist/path-normalize-BOQwY9wR.mjs +0 -23
- package/dist/path-normalize-BOQwY9wR.mjs.map +0 -1
- package/dist/types-DcYyNcHJ.d.mts.map +0 -1
- package/dist/utils-XWVecaNn.mjs.map +0 -1
|
@@ -1,11 +1,14 @@
|
|
|
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]="
|
|
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]="0af7e584-ef45-5330-b69b-706629bea4c2")}catch(e){}}();
|
|
3
|
+
import { createRequire } from "node:module";
|
|
3
4
|
import { gql } from "graphql-tag";
|
|
4
5
|
import { GraphQLError } from "graphql";
|
|
5
6
|
import { DRIVE_AUTH_ERROR_MESSAGES, RECOVERABLE_GRAPHQL_ERROR_CODES } from "@powerhousedao/reactor";
|
|
6
7
|
import { childLogger } from "document-model";
|
|
7
|
-
import path from "node:path";
|
|
8
|
+
import path, { dirname, isAbsolute, join } from "node:path";
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
8
10
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
|
+
import { packageJsonExports } from "@powerhousedao/shared/clis/constants";
|
|
9
12
|
//#region src/graphql/errors.ts
|
|
10
13
|
/** Caller (authenticated or anonymous) lacks permission for the document. */
|
|
11
14
|
var ForbiddenError = class extends GraphQLError {
|
|
@@ -68,6 +71,8 @@ var MalformedStoredOperationError = class extends GraphQLError {
|
|
|
68
71
|
* identifier when the check was skipped for a policy-wide caller.
|
|
69
72
|
*/
|
|
70
73
|
var AuthorizedDocumentHandle = class AuthorizedDocumentHandle {
|
|
74
|
+
fetchIdentifier;
|
|
75
|
+
isResolved;
|
|
71
76
|
constructor(fetchIdentifier, isResolved) {
|
|
72
77
|
this.fetchIdentifier = fetchIdentifier;
|
|
73
78
|
this.isResolved = isResolved;
|
|
@@ -91,6 +96,7 @@ const AuthorizationPolicy = {
|
|
|
91
96
|
};
|
|
92
97
|
/** Shared config holder and admin-list check for the policy strategies. */
|
|
93
98
|
var BaseAuthorizationService = class {
|
|
99
|
+
config;
|
|
94
100
|
constructor(config) {
|
|
95
101
|
this.config = config;
|
|
96
102
|
}
|
|
@@ -268,6 +274,16 @@ function createCanonicalDocumentIdResolver(client) {
|
|
|
268
274
|
}
|
|
269
275
|
//#endregion
|
|
270
276
|
//#region src/graphql/base-subgraph.ts
|
|
277
|
+
/**
|
|
278
|
+
* The subject a request reads as: its address and the app key its token
|
|
279
|
+
* carries. Anonymous is an empty subject, never the host's signer.
|
|
280
|
+
*/
|
|
281
|
+
function callerSubject(user) {
|
|
282
|
+
return {
|
|
283
|
+
address: user?.address,
|
|
284
|
+
key: user?.appKey
|
|
285
|
+
};
|
|
286
|
+
}
|
|
271
287
|
var BaseSubgraph = class {
|
|
272
288
|
name = "example";
|
|
273
289
|
path = "";
|
|
@@ -372,10 +388,16 @@ var BaseSubgraph = class {
|
|
|
372
388
|
* carries the same key. Anonymous callers supply neither.
|
|
373
389
|
*/
|
|
374
390
|
viewSubject(ctx) {
|
|
375
|
-
return
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
391
|
+
return callerSubject(ctx.user);
|
|
392
|
+
}
|
|
393
|
+
/** Whether a listing would serve the document to the caller; fails closed. */
|
|
394
|
+
async servesDocument(documentId, ctx) {
|
|
395
|
+
if (!documentId) return false;
|
|
396
|
+
try {
|
|
397
|
+
return await this.reactorClient.isServed(documentId, { subject: this.viewSubject(ctx) });
|
|
398
|
+
} catch {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
379
401
|
}
|
|
380
402
|
/**
|
|
381
403
|
* Asserts read access, resolving a slug first. Returns a handle whose
|
|
@@ -647,7 +669,122 @@ function buildGraphQlDriveDocument(doc) {
|
|
|
647
669
|
};
|
|
648
670
|
}
|
|
649
671
|
//#endregion
|
|
650
|
-
|
|
672
|
+
//#region src/packages/pieces.ts
|
|
673
|
+
/** The sub-entry every loader asks a package for its pieces through. */
|
|
674
|
+
const PIECES_SUBPATH = "pieces";
|
|
675
|
+
const BUILT_PIECE_LIST = packageJsonExports["./pieces"].node;
|
|
676
|
+
/** Where a package keeps its piece sources, for telling unbuilt from absent. */
|
|
677
|
+
const PIECE_SOURCE_LIST = join(PIECES_SUBPATH, "index.ts");
|
|
678
|
+
/** The nearest enclosing package.json, which `exports` usually hides. */
|
|
679
|
+
function packageRootOf(dir) {
|
|
680
|
+
let current = dir;
|
|
681
|
+
while (!existsSync(join(current, "package.json"))) {
|
|
682
|
+
const parent = dirname(current);
|
|
683
|
+
if (parent === current) return void 0;
|
|
684
|
+
current = parent;
|
|
685
|
+
}
|
|
686
|
+
return current;
|
|
687
|
+
}
|
|
688
|
+
function resolvePieceList(specifier, hostDir) {
|
|
689
|
+
try {
|
|
690
|
+
return fileURLToPath(import.meta.resolve(specifier));
|
|
691
|
+
} catch (error) {
|
|
692
|
+
try {
|
|
693
|
+
return createRequire(join(hostDir, "package.json")).resolve(specifier);
|
|
694
|
+
} catch {
|
|
695
|
+
throw error;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
function pieceListLocation(identifier, hostDir = process.cwd()) {
|
|
700
|
+
if (isAbsolute(identifier)) return {
|
|
701
|
+
root: identifier,
|
|
702
|
+
listPath: join(identifier, BUILT_PIECE_LIST)
|
|
703
|
+
};
|
|
704
|
+
const listPath = resolvePieceList(`${identifier}/${PIECES_SUBPATH}`, hostDir);
|
|
705
|
+
const root = packageRootOf(dirname(listPath));
|
|
706
|
+
if (!root) throw new Error(`No package.json above ${listPath}`);
|
|
707
|
+
return {
|
|
708
|
+
root,
|
|
709
|
+
listPath
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
function packageVersionAt(root) {
|
|
713
|
+
try {
|
|
714
|
+
const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
715
|
+
return typeof pkg.version === "string" && pkg.version !== "" ? pkg.version : void 0;
|
|
716
|
+
} catch {
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function locatePieces(declared, context) {
|
|
721
|
+
const { root, identifier, logger, version } = context;
|
|
722
|
+
const located = [];
|
|
723
|
+
for (const piece of declared) {
|
|
724
|
+
const where = piece.entry ?? piece.bundle;
|
|
725
|
+
if (typeof where !== "string" || where === "") {
|
|
726
|
+
logger.warn("Piece @piece of @pkg declares neither a bundle nor an entry", piece.name, identifier);
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
const path = isAbsolute(where) ? where : join(root, where);
|
|
730
|
+
if (!(piece.entry ? existsSync(path) : existsSync(join(path, "package.json")))) {
|
|
731
|
+
logger.warn("Piece @piece of @pkg is declared but not built at @path", piece.name, identifier, path);
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
located.push({
|
|
735
|
+
name: piece.name,
|
|
736
|
+
version,
|
|
737
|
+
...piece.entry ? { entryPath: path } : { bundleDir: path }
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
return located;
|
|
741
|
+
}
|
|
742
|
+
function declaredPieces(module, identifier, logger) {
|
|
743
|
+
const namespace = module ?? {};
|
|
744
|
+
const declared = namespace.pieces ?? namespace.default;
|
|
745
|
+
if (!Array.isArray(declared)) {
|
|
746
|
+
logger.warn("The pieces list of @pkg exports no \"pieces\" array; it contributes none", identifier);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
return declared;
|
|
750
|
+
}
|
|
751
|
+
function piecesFromCdnList(module, baseUrl, identifier, logger, version) {
|
|
752
|
+
const declared = declaredPieces(module, identifier, logger);
|
|
753
|
+
if (!declared) return [];
|
|
754
|
+
const located = [];
|
|
755
|
+
for (const piece of declared) {
|
|
756
|
+
const where = piece.entry ?? piece.bundle;
|
|
757
|
+
if (typeof where !== "string" || where === "") {
|
|
758
|
+
logger.warn("Piece @piece of @pkg declares neither a bundle nor an entry", piece.name, identifier);
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
located.push({
|
|
762
|
+
name: piece.name,
|
|
763
|
+
version,
|
|
764
|
+
entryUrl: `${baseUrl}${where.replace(/^dist\/node\/pieces\//, "")}`
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
return located;
|
|
768
|
+
}
|
|
769
|
+
function piecesFromListModule(module, context) {
|
|
770
|
+
const namespace = module ?? {};
|
|
771
|
+
const declared = namespace.pieces ?? namespace.default;
|
|
772
|
+
if (!Array.isArray(declared)) {
|
|
773
|
+
context.logger.warn("The pieces list of @pkg exports no \"pieces\" array; it contributes none", context.identifier);
|
|
774
|
+
return [];
|
|
775
|
+
}
|
|
776
|
+
const version = packageVersionAt(context.root);
|
|
777
|
+
if (!version) {
|
|
778
|
+
context.logger.warn("@pkg has no version in @root/package.json, and a piece takes its package's version; its pieces contribute none", context.identifier, context.root);
|
|
779
|
+
return [];
|
|
780
|
+
}
|
|
781
|
+
return locatePieces(declared, {
|
|
782
|
+
...context,
|
|
783
|
+
version
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
//#endregion
|
|
787
|
+
export { AuthorizedDocumentHandle as C, ForbiddenError as D, AuthenticationRequiredError as E, MalformedStoredOperationError as O, AuthorizationPolicy as S, AuthEvaluationUnsupportedError as T, loadSubgraphs as _, piecesFromCdnList as a, CanonicalDocumentIdResolutionError as b, buildGraphQlDriveDocument as c, isSubgraphClass as d, debounce as f, loadProcessors as g, loadDocumentModels as h, pieceListLocation as i, buildGraphqlOperation as l, isSubpath as m, PIECES_SUBPATH as n, piecesFromListModule as o, extractUpgradeManifests as p, PIECE_SOURCE_LIST as r, buildGraphQlDocument as s, BUILT_PIECE_LIST as t, buildGraphqlOperations as u, BaseSubgraph as v, createAuthorizationService as w, createCanonicalDocumentIdResolver as x, callerSubject as y };
|
|
651
788
|
|
|
652
|
-
//# sourceMappingURL=
|
|
653
|
-
//# debugId=
|
|
789
|
+
//# sourceMappingURL=pieces-WWMZBM0n.mjs.map
|
|
790
|
+
//# debugId=0af7e584-ef45-5330-b69b-706629bea4c2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pieces-WWMZBM0n.mjs","sources":["../src/graphql/errors.ts","../src/services/authorization.service.ts","../src/services/canonical-document-id.ts","../src/graphql/base-subgraph.ts","../src/packages/import-resolver.ts","../src/packages/util.ts","../src/graphql/utils.ts","../src/packages/pieces.ts"],"sourcesContent":["import { GraphQLError } from \"graphql\";\nimport {\n DRIVE_AUTH_ERROR_MESSAGES,\n RECOVERABLE_GRAPHQL_ERROR_CODES,\n} from \"@powerhousedao/reactor\";\n\n/** Caller (authenticated or anonymous) lacks permission for the document. */\nexport class ForbiddenError extends GraphQLError {\n constructor(detail = \"\") {\n const base = DRIVE_AUTH_ERROR_MESSAGES.forbidden;\n super(`${base}${detail ? ` ${detail}` : \"\"}`, {\n extensions: { code: \"FORBIDDEN\" },\n });\n }\n}\n\n/** Anonymous caller on an action that requires logging in. */\nexport class AuthenticationRequiredError extends GraphQLError {\n constructor(detail = \"\") {\n const base = DRIVE_AUTH_ERROR_MESSAGES.authenticationRequired;\n super(`${base}${detail ? ` ${detail}` : \"\"}`, {\n extensions: { code: \"UNAUTHENTICATED\" },\n });\n }\n}\n\n/**\n * The reactor holds no decision model, so no authorization preflight can be\n * answered.\n *\n * Distinct from a denial, and deliberately so: a caller that cannot get a\n * prediction should render its controls as it did before it asked and let the\n * submit path refuse. Reading this as a denial would disable every control on a\n * switchboard running without authEnforcement. The code is what a client\n * branches on, since the message is not a contract.\n */\nexport class AuthEvaluationUnsupportedError extends GraphQLError {\n constructor() {\n super(\n \"Authorization evaluation is unavailable: this reactor runs without the \" +\n \"authEnforcement feature flag, so it holds no decision model\",\n { extensions: { code: \"AUTH_EVALUATION_UNSUPPORTED\" } },\n );\n }\n}\n\n/**\n * A stored operation cannot be represented in the schema, so it is reported\n * rather than served.\n *\n * The schema declares an action's id, type, timestamp, input and scope\n * non-null; an operation written before the API rejected an action without an\n * id violates that. Left to the executor, the missing value nullifies the\n * action, which bubbles up through the non-null chain until it nullifies the\n * envelope's whole operation list, and the caller receives a partial response\n * beside \"Cannot return null for non-nullable field Action.id\" - which says\n * nothing about which operation, and which a sync client can only read as a\n * permanent GraphQL rejection, stopping its poll timer for good.\n *\n * Thrown instead, with a code that says the failure is worth polling through:\n * the document holding the operation needs repairing, but the channel serves\n * every other document, and a peer that stopped polling would stop receiving\n * those too. The code is what a client branches on, since the message is not a\n * contract.\n */\nexport class MalformedStoredOperationError extends GraphQLError {\n constructor(detail: string) {\n super(`Stored operation cannot be served: ${detail}`, {\n extensions: {\n code: RECOVERABLE_GRAPHQL_ERROR_CODES.malformedStoredOperation,\n },\n });\n }\n}\n","import type { DocumentPermissionLevel } from \"../utils/db.js\";\nimport type {\n DocumentPermissionService,\n GetParentIdsFn,\n} from \"./document-permission.service.js\";\n\n/**\n * A document id that has been resolved to its canonical form, never a slug.\n *\n * Protection and grant rows are written under the canonical id, while the\n * read/operation data paths accept an id-or-slug identifier. The decision layer\n * must key on the canonical id, so branding it forces every caller to resolve a\n * slug to its id before consulting this service, closing the slug-aliasing\n * bypass (S-C1). The only sanctioned cast from string to CanonicalDocumentId\n * lives in createCanonicalDocumentIdResolver, immediately after the shared\n * resolveIdOrSlug lookup returns.\n */\nexport type CanonicalDocumentId = string & {\n readonly __canonicalDocumentId: unique symbol;\n};\n\n/**\n * Result of a passed per-document authorization check. `fetchIdentifier` is\n * always safe for the data fetch: the canonical id when resolved, or the raw\n * identifier when the check was skipped for a policy-wide caller.\n */\nexport class AuthorizedDocumentHandle {\n private constructor(\n readonly fetchIdentifier: string,\n readonly isResolved: boolean,\n ) {}\n\n static resolved(documentId: CanonicalDocumentId): AuthorizedDocumentHandle {\n return new AuthorizedDocumentHandle(documentId, true);\n }\n\n static skipped(identifier: string): AuthorizedDocumentHandle {\n return new AuthorizedDocumentHandle(identifier, false);\n }\n\n /** The verified canonical id; throws when resolution was skipped. */\n canonicalId(): CanonicalDocumentId {\n if (!this.isResolved) {\n throw new Error(\n \"Canonical document id is unavailable: the authorization check was skipped for a policy-wide caller\",\n );\n }\n return this.fetchIdentifier as CanonicalDocumentId;\n }\n}\n\nexport const AuthorizationPolicy = {\n OPEN: \"OPEN\",\n ADMIN_ONLY: \"ADMIN_ONLY\",\n DOCUMENT_PERMISSIONS: \"DOCUMENT_PERMISSIONS\",\n} as const;\n\nexport type AuthorizationPolicy =\n (typeof AuthorizationPolicy)[keyof typeof AuthorizationPolicy];\n\nexport interface AuthorizationConfig {\n admins: string[];\n defaultProtection: boolean;\n policy: AuthorizationPolicy;\n}\n\n/**\n * Single source of truth for every permission decision. Always present (never\n * null) so callers branch on data, not on the existence of a service.\n *\n * The policy selects an implementation once at boot:\n * - OPEN: authentication disabled — everyone (incl. anonymous) is allowed.\n * - ADMIN_ONLY: authentication on, document permissions off — only ADMINS.\n * - DOCUMENT_PERMISSIONS: the full per-document protection + grant model.\n *\n * Permission inheritance walks the parent-document hierarchy through a\n * parent resolver injected at construction; callers never supply one.\n */\nexport interface IAuthorizationService {\n readonly config: AuthorizationConfig;\n\n /**\n * Whether the user has unrestricted, policy-wide access. Under OPEN this is\n * true for everyone (including anonymous callers) by design: OPEN means \"no\n * restrictions\", and consumers use this check to skip per-document\n * filtering. It does NOT mean the caller is in the ADMINS list.\n */\n isSupremeAdmin(userAddress?: string): boolean;\n\n /**\n * Whether the user may create new documents under the current policy:\n * everyone in OPEN, only admins in ADMIN_ONLY, any authenticated user in\n * DOCUMENT_PERMISSIONS.\n */\n canCreate(userAddress?: string): boolean;\n\n canRead(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean>;\n\n canWrite(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean>;\n\n /**\n * Whether the user administers the document: supreme admin, document\n * owner, or holder of an ADMIN grant.\n */\n canManage(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean>;\n\n canMutate(\n documentId: CanonicalDocumentId,\n operationType: string,\n userAddress?: string,\n ): Promise<boolean>;\n}\n\n/** Shared config holder and admin-list check for the policy strategies. */\nabstract class BaseAuthorizationService implements IAuthorizationService {\n constructor(readonly config: AuthorizationConfig) {}\n\n isSupremeAdmin(userAddress?: string): boolean {\n if (!userAddress) return false;\n return this.config.admins.includes(userAddress.toLowerCase());\n }\n\n abstract canCreate(userAddress?: string): boolean;\n\n abstract canRead(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean>;\n\n abstract canWrite(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean>;\n\n abstract canManage(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean>;\n\n abstract canMutate(\n documentId: CanonicalDocumentId,\n operationType: string,\n userAddress?: string,\n ): Promise<boolean>;\n}\n\n/** OPEN: authentication disabled — everyone (incl. anonymous) is allowed. */\nclass OpenAuthorizationService extends BaseAuthorizationService {\n isSupremeAdmin(): boolean {\n return true;\n }\n\n canCreate(): boolean {\n return true;\n }\n\n canRead(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n canWrite(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n canManage(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n canMutate(): Promise<boolean> {\n return Promise.resolve(true);\n }\n}\n\n/** ADMIN_ONLY: authentication on, document permissions off — only ADMINS. */\nclass AdminOnlyAuthorizationService extends BaseAuthorizationService {\n canCreate(userAddress?: string): boolean {\n return this.isSupremeAdmin(userAddress);\n }\n\n canRead(\n _documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean> {\n return Promise.resolve(this.isSupremeAdmin(userAddress));\n }\n\n canWrite(\n _documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean> {\n return Promise.resolve(this.isSupremeAdmin(userAddress));\n }\n\n canManage(\n _documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean> {\n return Promise.resolve(this.isSupremeAdmin(userAddress));\n }\n\n canMutate(\n _documentId: CanonicalDocumentId,\n _operationType: string,\n userAddress?: string,\n ): Promise<boolean> {\n return Promise.resolve(this.isSupremeAdmin(userAddress));\n }\n}\n\nconst PERMISSION_RANK: Record<DocumentPermissionLevel, number> = {\n READ: 1,\n WRITE: 2,\n ADMIN: 3,\n};\n\nfunction satisfies(\n level: DocumentPermissionLevel | null,\n required: DocumentPermissionLevel,\n): boolean {\n return level !== null && PERMISSION_RANK[level] >= PERMISSION_RANK[required];\n}\n\n/**\n * DOCUMENT_PERMISSIONS: the full per-document protection + grant model.\n *\n * All decisions live here; DocumentPermissionService is the data-access\n * layer underneath (grants, protection rows, owners).\n */\nclass DocumentPermissionsAuthorizationService extends BaseAuthorizationService {\n readonly #permissions: DocumentPermissionService;\n readonly #getParentIds: GetParentIdsFn;\n\n constructor(\n permissions: DocumentPermissionService,\n getParentIds: GetParentIdsFn,\n config: AuthorizationConfig,\n ) {\n super(config);\n this.#permissions = permissions;\n this.#getParentIds = getParentIds;\n }\n\n canCreate(userAddress?: string): boolean {\n return this.isSupremeAdmin(userAddress) || !!userAddress;\n }\n\n canRead(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean> {\n return this.#canAccess(documentId, \"READ\", userAddress);\n }\n\n canWrite(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean> {\n return this.#canAccess(documentId, \"WRITE\", userAddress);\n }\n\n canManage(\n documentId: CanonicalDocumentId,\n userAddress?: string,\n ): Promise<boolean> {\n return this.#isDocumentAdmin(documentId, userAddress);\n }\n\n async canMutate(\n documentId: CanonicalDocumentId,\n operationType: string,\n userAddress?: string,\n ): Promise<boolean> {\n if (this.isSupremeAdmin(userAddress)) return true;\n\n const isRestricted = await this.#permissions.isOperationRestricted(\n documentId,\n operationType,\n );\n if (isRestricted) {\n if (!userAddress) return false;\n if (await this.#isDocumentAdmin(documentId, userAddress)) return true;\n return this.#permissions.hasOperationGrant(\n documentId,\n operationType,\n userAddress,\n );\n }\n\n return this.#canAccess(documentId, \"WRITE\", userAddress);\n }\n\n /**\n * The one \"administers this document\" predicate: supreme admin, document\n * owner, or ADMIN grant on the document itself.\n */\n async #isDocumentAdmin(\n documentId: string,\n userAddress?: string,\n ): Promise<boolean> {\n if (this.isSupremeAdmin(userAddress)) return true;\n if (!userAddress) return false;\n\n const owner = await this.#permissions.getDocumentOwner(documentId);\n if (owner && owner === userAddress.toLowerCase()) return true;\n\n return satisfies(await this.#grantLevel(documentId, userAddress), \"ADMIN\");\n }\n\n /**\n * The one read/write decision shape: supreme admin → unprotected (self or\n * ancestor) → owner → inherited grant of at least the required level.\n */\n async #canAccess(\n documentId: string,\n required: DocumentPermissionLevel,\n userAddress?: string,\n ): Promise<boolean> {\n if (this.isSupremeAdmin(userAddress)) return true;\n\n const isProtected = await this.#permissions.isProtectedWithAncestors(\n documentId,\n this.#getParentIds,\n );\n if (!isProtected) return true;\n if (!userAddress) return false;\n\n const owner = await this.#permissions.getDocumentOwner(documentId);\n if (owner && owner === userAddress.toLowerCase()) return true;\n\n return this.#hasGrantInHierarchy(documentId, userAddress, required);\n }\n\n /** Best grant the user holds on the document. */\n async #grantLevel(\n documentId: string,\n userAddress: string,\n ): Promise<DocumentPermissionLevel | null> {\n return this.#permissions.getUserPermission(documentId, userAddress);\n }\n\n /**\n * Walks the parent hierarchy (with cycle protection) looking for a grant of\n * at least the required level on the document or any ancestor.\n */\n async #hasGrantInHierarchy(\n documentId: string,\n userAddress: string,\n required: DocumentPermissionLevel,\n ): Promise<boolean> {\n const visited = new Set<string>();\n const queue = [documentId];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) continue;\n visited.add(current);\n\n const level = await this.#grantLevel(current, userAddress);\n if (satisfies(level, required)) return true;\n\n for (const parentId of await this.#getParentIds(current)) {\n if (!visited.has(parentId)) queue.push(parentId);\n }\n }\n\n return false;\n }\n}\n\n/**\n * Selects the strategy for the configured policy. The strategy classes are\n * not exported, so this guard is the only construction path.\n */\nexport function createAuthorizationService(\n config: AuthorizationConfig,\n documentPermissionService?: DocumentPermissionService,\n getParentIds?: GetParentIdsFn,\n): IAuthorizationService {\n if (config.policy === AuthorizationPolicy.OPEN) {\n return new OpenAuthorizationService(config);\n }\n if (config.policy === AuthorizationPolicy.ADMIN_ONLY) {\n return new AdminOnlyAuthorizationService(config);\n }\n if (!documentPermissionService) {\n throw new Error(\n \"DocumentPermissionService is required for the DOCUMENT_PERMISSIONS policy\",\n );\n }\n if (!getParentIds) {\n throw new Error(\n \"A getParentIds resolver is required for the DOCUMENT_PERMISSIONS policy\",\n );\n }\n return new DocumentPermissionsAuthorizationService(\n documentPermissionService,\n getParentIds,\n config,\n );\n}\n","import type { IReactorClient } from \"@powerhousedao/reactor\";\nimport type { CanonicalDocumentId } from \"./authorization.service.js\";\n\n/**\n * Raised when a caller-supplied identifier cannot be resolved to a canonical\n * document id. Carries no detail on purpose: resolution failures must not act\n * as a document-existence oracle, so consumers map this to their generic\n * fail-closed response.\n */\nexport class CanonicalDocumentIdResolutionError extends Error {\n constructor() {\n super(\"Document identifier could not be resolved\");\n this.name = \"CanonicalDocumentIdResolutionError\";\n }\n}\n\nexport type CanonicalDocumentIdResolver = (\n identifier: string,\n) => Promise<CanonicalDocumentId>;\n\n/**\n * The sanctioned string-to-CanonicalDocumentId cast: both the GraphQL layer\n * and server routes must resolve caller identifiers through this helper so\n * decision and data layers always agree on the subject document.\n */\nexport function createCanonicalDocumentIdResolver(\n client: Pick<IReactorClient, \"resolveIdOrSlug\">,\n): CanonicalDocumentIdResolver {\n return async (identifier: string) => {\n let resolved: string;\n try {\n resolved = await client.resolveIdOrSlug(identifier);\n } catch {\n throw new CanonicalDocumentIdResolutionError();\n }\n return resolved as CanonicalDocumentId;\n };\n}\n","import type {\n IReactorClient,\n IRelationalDb,\n ISyncManager,\n SyncScopeGate,\n} from \"@powerhousedao/reactor\";\nimport type { AuthSubject } from \"@powerhousedao/shared/document-model\";\nimport type {\n GraphQLManager,\n ISubgraph,\n SubgraphArgs,\n} from \"@powerhousedao/reactor-api\";\nimport type { DocumentNode } from \"graphql\";\nimport { ForbiddenError, AuthenticationRequiredError } from \"./errors.js\";\nimport { gql } from \"graphql-tag\";\nimport {\n AuthorizationPolicy,\n AuthorizedDocumentHandle,\n type CanonicalDocumentId,\n type IAuthorizationService,\n} from \"../services/authorization.service.js\";\nimport {\n createCanonicalDocumentIdResolver,\n type CanonicalDocumentIdResolver,\n} from \"../services/canonical-document-id.js\";\nimport type { DocumentPermissionService } from \"../services/document-permission.service.js\";\nimport type { Context } from \"./types.js\";\n\n/**\n * The subject a request reads as: its address and the app key its token\n * carries. Anonymous is an empty subject, never the host's signer.\n */\nexport function callerSubject(user: Context[\"user\"]): AuthSubject {\n return { address: user?.address, key: user?.appKey };\n}\n\nexport class BaseSubgraph implements ISubgraph {\n name = \"example\";\n // The host's base path as injected by the GraphQL manager. Routing\n // ignores it: the manager mounts every subgraph under its own base path.\n path = \"\";\n resolvers: Record<string, any> = {\n Query: {\n hello: () => this.name,\n },\n };\n typeDefs: DocumentNode = gql`\n type Query {\n hello: String\n }\n `;\n reactorClient: IReactorClient;\n /** This package's namespaced slice of the HTTP surface. */\n readonly http: SubgraphArgs[\"http\"];\n graphqlManager: GraphQLManager;\n relationalDb: IRelationalDb;\n syncManager: ISyncManager;\n documentPermissionService?: DocumentPermissionService;\n authorizationService: IAuthorizationService;\n syncServingGate?: SyncScopeGate;\n\n /**\n * Per-request memo of raw identifier to canonical document id, keyed on the\n * request context object so entries are released when the request ends. Lets\n * batch resolvers resolve each distinct identifier at most once.\n */\n readonly #canonicalIdMemo = new WeakMap<\n object,\n Map<string, CanonicalDocumentId>\n >();\n\n readonly #resolveCanonical: CanonicalDocumentIdResolver;\n\n constructor(args: SubgraphArgs) {\n this.#resolveCanonical = createCanonicalDocumentIdResolver(\n args.reactorClient,\n );\n this.http = args.http;\n this.reactorClient = args.reactorClient;\n this.graphqlManager = args.graphqlManager;\n this.relationalDb = args.relationalDb;\n this.syncManager = args.syncManager;\n this.documentPermissionService = args.documentPermissionService;\n this.authorizationService = args.authorizationService;\n this.syncServingGate = args.syncServingGate;\n this.path = args.path ?? \"\";\n }\n\n async onSetup() {\n // noop\n }\n\n async onDisconnect(): Promise<void> {\n // noop\n }\n\n // ============================================\n // Shared permission helpers\n // ============================================\n\n /**\n * Resolves a caller-supplied identifier (id or slug) to its canonical\n * document id, memoized per request. Both the decision layer and the data\n * layer must agree on the subject, so this runs the same resolveIdOrSlug\n * lookup the data path uses. A resolution failure (not found, ambiguous, or\n * transient) surfaces as a generic Forbidden, fail-closed, so a bad\n * identifier cannot be used as a document-existence oracle.\n */\n async resolveCanonicalDocumentId(\n identifier: string,\n requestKey: object,\n ): Promise<CanonicalDocumentId> {\n let cache = this.#canonicalIdMemo.get(requestKey);\n if (!cache) {\n cache = new Map<string, CanonicalDocumentId>();\n this.#canonicalIdMemo.set(requestKey, cache);\n }\n\n const cached = cache.get(identifier);\n if (cached !== undefined) return cached;\n\n let canonical: CanonicalDocumentId;\n try {\n canonical = await this.#resolveCanonical(identifier);\n } catch {\n throw new ForbiddenError();\n }\n\n cache.set(identifier, canonical);\n return canonical;\n }\n\n /**\n * Resolves the args' `documentId` to canonical form. Unconditional (unlike the\n * assertCan* helpers, no admin skip): ACL rows are keyed on the canonical id.\n */\n async withCanonicalDocumentId<T extends { documentId: string }>(\n args: T,\n requestKey: object,\n ): Promise<T & { documentId: CanonicalDocumentId }> {\n const documentId = await this.resolveCanonicalDocumentId(\n args.documentId,\n requestKey,\n );\n return { ...args, documentId };\n }\n\n /**\n * Resolves an identifier for a per-document check, or null when the caller has\n * policy-wide access (OPEN or supreme admin) and the check can be skipped.\n * Only DOCUMENT_PERMISSIONS keys on the document id, so other policies fail\n * closed without resolving.\n */\n async #resolveForCheck(\n identifier: string,\n ctx: Context,\n ): Promise<CanonicalDocumentId | null> {\n if (this.authorizationService.isSupremeAdmin(ctx.user?.address)) {\n return null;\n }\n if (\n this.authorizationService.config.policy !==\n AuthorizationPolicy.DOCUMENT_PERMISSIONS\n ) {\n throw new ForbiddenError();\n }\n return this.resolveCanonicalDocumentId(identifier, ctx);\n }\n\n /**\n * Read filter for an already-canonical document id (one sourced from the data\n * layer, such as a fetched document's id). Performs no slug resolution.\n */\n async canReadDocument(\n documentId: CanonicalDocumentId,\n ctx: Context,\n ): Promise<boolean> {\n return this.authorizationService.canRead(documentId, ctx.user?.address);\n }\n\n /**\n * The principal a request decides as: the authenticated caller's address, and\n * the did:key of the app instance whose token authenticated it.\n *\n * Both, because a policy can name either. The key is what a document records\n * as its creator, so a subject built without one cannot match the creator's\n * standing permission over the auth scope -- the document's own creator would\n * be refused an operation the write path accepts, since a signed action\n * carries the same key. Anonymous callers supply neither.\n */\n protected viewSubject(ctx: Context): AuthSubject {\n return callerSubject(ctx.user);\n }\n\n /** Whether a listing would serve the document to the caller; fails closed. */\n protected async servesDocument(\n documentId: string,\n ctx: Context,\n ): Promise<boolean> {\n if (!documentId) {\n return false;\n }\n try {\n return await this.reactorClient.isServed(documentId, {\n subject: this.viewSubject(ctx),\n });\n } catch {\n return false;\n }\n }\n\n /**\n * Asserts read access, resolving a slug first. Returns a handle whose\n * `fetchIdentifier` the caller reuses for the data fetch; a denial throws.\n */\n async assertCanRead(\n identifier: string,\n ctx: Context,\n ): Promise<AuthorizedDocumentHandle> {\n const documentId = await this.#resolveForCheck(identifier, ctx);\n if (documentId === null)\n return AuthorizedDocumentHandle.skipped(identifier);\n await this.assertCanReadCanonical(documentId, ctx);\n return AuthorizedDocumentHandle.resolved(documentId);\n }\n\n async assertCanWrite(\n identifier: string,\n ctx: Context,\n ): Promise<AuthorizedDocumentHandle> {\n const documentId = await this.#resolveForCheck(identifier, ctx);\n if (documentId === null)\n return AuthorizedDocumentHandle.skipped(identifier);\n await this.assertCanWriteCanonical(documentId, ctx);\n return AuthorizedDocumentHandle.resolved(documentId);\n }\n\n async assertCanExecuteOperation(\n identifier: string,\n operationType: string,\n ctx: Context,\n ): Promise<AuthorizedDocumentHandle> {\n const documentId = await this.#resolveForCheck(identifier, ctx);\n if (documentId === null)\n return AuthorizedDocumentHandle.skipped(identifier);\n await this.assertCanExecuteOperationCanonical(\n documentId,\n operationType,\n ctx,\n );\n return AuthorizedDocumentHandle.resolved(documentId);\n }\n\n /**\n * Read assertion for an already-canonical document id. No slug resolution;\n * use only with ids sourced from the data layer or already resolved.\n */\n async assertCanReadCanonical(\n documentId: CanonicalDocumentId,\n ctx: Context,\n ): Promise<void> {\n const canRead = await this.authorizationService.canRead(\n documentId,\n ctx.user?.address,\n );\n if (!canRead) {\n throw new ForbiddenError(\"to read this document\");\n }\n }\n\n async assertCanWriteCanonical(\n documentId: CanonicalDocumentId,\n ctx: Context,\n ): Promise<void> {\n const canWrite = await this.authorizationService.canWrite(\n documentId,\n ctx.user?.address,\n );\n if (!canWrite) {\n throw new ForbiddenError(\"to write to this document\");\n }\n }\n\n async assertCanExecuteOperationCanonical(\n documentId: CanonicalDocumentId,\n operationType: string,\n ctx: Context,\n ): Promise<void> {\n const canMutate = await this.authorizationService.canMutate(\n documentId,\n operationType,\n ctx.user?.address,\n );\n if (!canMutate) {\n throw new ForbiddenError(\n `to execute operation \"${operationType}\" on this document`,\n );\n }\n }\n\n assertCanCreate(ctx: Context): void {\n if (this.authorizationService.canCreate(ctx.user?.address)) return;\n if (ctx.user?.address) {\n throw new ForbiddenError(\"to create documents\");\n }\n throw new AuthenticationRequiredError(\"to create documents\");\n }\n}\n","import path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\n/**\n * Imports a specifier that may be either a bare package specifier or a\n * filesystem path. Absolute paths are converted to file:// URLs, because the\n * ESM loader reads the drive letter in a Windows path as a URL scheme\n * (`import('D:\\\\...')` fails with ERR_UNSUPPORTED_ESM_URL_SCHEME).\n */\nasync function importSpecifier<T>(target: string): Promise<T> {\n const specifier = path.isAbsolute(target)\n ? pathToFileURL(target).href\n : target;\n return (await import(/* @vite-ignore */ specifier)) as T;\n}\n\n/**\n * Attempts to import from suggested Node.js paths\n */\nasync function tryNodeSuggestedPaths<T>(\n packageName: string,\n subPath: string,\n): Promise<T | null> {\n const suggestedPaths = [\n `${packageName}/dist/node/${subPath}/index.mjs`,\n `${packageName}/dist/node/${subPath}.mjs`,\n `${packageName}/dist/${subPath}/index.js`,\n `${packageName}/dist/${subPath}.js`,\n ];\n\n for (const suggestedPath of suggestedPaths) {\n try {\n return await importSpecifier<T>(suggestedPath);\n } catch {\n // Continue to next attempt\n }\n }\n\n return null;\n}\n\n/**\n * Attempts to resolve package using import.meta.resolve\n */\nasync function tryImportMetaResolve<T>(\n packageName: string,\n subPath: string,\n): Promise<T | null> {\n try {\n const resolvedUrl = import.meta.resolve?.(`${packageName}/package.json`);\n if (!resolvedUrl) return null;\n\n // fileURLToPath, not URL.pathname: the latter yields \"/D:/...\" on Windows.\n const packageRoot = path.dirname(fileURLToPath(resolvedUrl));\n const pathsToTry = [\n path.join(packageRoot, \"dist\", \"node\", subPath, \"index.mjs\"),\n path.join(packageRoot, \"dist\", \"node\", `${subPath}.mjs`),\n path.join(packageRoot, \"dist\", subPath, \"index.js\"),\n path.join(packageRoot, \"dist\", `${subPath}.js`),\n path.join(packageRoot, subPath, \"index.js\"),\n path.join(packageRoot, `${subPath}.js`),\n ];\n\n for (const attemptPath of pathsToTry) {\n try {\n return await importSpecifier<T>(attemptPath);\n } catch {\n // Continue to next attempt\n }\n }\n } catch {\n // import.meta.resolve failed\n }\n\n return null;\n}\n\n/**\n * Resolves symlinks in node_modules to find the real package location\n */\nasync function resolveSymlinkedPaths(\n packageName: string,\n subPath: string,\n): Promise<string[]> {\n const packageBaseName = packageName.includes(\"/\")\n ? packageName.split(\"/\").pop()\n : packageName;\n const nodeModulesPatterns = [\n path.join(process.cwd(), \"node_modules\", packageName),\n path.join(process.cwd(), \"node_modules\", packageBaseName || packageName),\n ];\n\n const workspacePatterns: string[] = [];\n\n for (const nodeModulesPath of nodeModulesPatterns) {\n try {\n const fs = await import(\"node:fs\");\n if (fs.existsSync(nodeModulesPath)) {\n const realPath = fs.realpathSync(nodeModulesPath);\n\n workspacePatterns.push(\n path.join(realPath, \"dist\", \"node\", subPath, \"index.mjs\"),\n path.join(realPath, \"dist\", \"node\", `${subPath}.mjs`),\n path.join(realPath, \"dist\", subPath, \"index.js\"),\n path.join(realPath, \"dist\", `${subPath}.js`),\n path.join(realPath, subPath, \"index.js\"),\n path.join(realPath, `${subPath}.js`),\n );\n }\n } catch {\n // Continue to next attempt\n }\n }\n\n return workspacePatterns;\n}\n\n/**\n * Generates common workspace pattern paths\n */\nfunction getCommonWorkspacePaths(\n packageName: string,\n subPath: string,\n): string[] {\n const packageBaseName = packageName.includes(\"/\")\n ? packageName.split(\"/\").pop()\n : packageName;\n const commonRoots = [process.cwd(), path.dirname(process.cwd())];\n\n const workspacePatterns: string[] = [];\n for (const root of commonRoots) {\n workspacePatterns.push(\n path.join(\n root,\n \"packages\",\n packageBaseName || packageName,\n \"dist\",\n \"node\",\n subPath,\n \"index.mjs\",\n ),\n path.join(\n root,\n \"packages\",\n packageBaseName || packageName,\n \"dist\",\n \"node\",\n `${subPath}.mjs`,\n ),\n path.join(\n root,\n \"packages\",\n packageBaseName || packageName,\n \"dist\",\n subPath,\n \"index.js\",\n ),\n path.join(\n root,\n \"packages\",\n packageBaseName || packageName,\n \"dist\",\n `${subPath}.js`,\n ),\n );\n }\n\n return workspacePatterns;\n}\n\n/**\n * Attempts to import from a list of workspace patterns\n */\nasync function tryWorkspacePatterns<T>(patterns: string[]): Promise<T | null> {\n for (const workspacePath of patterns) {\n try {\n return await importSpecifier<T>(workspacePath);\n } catch {\n // Continue to next attempt\n }\n }\n\n return null;\n}\n\n/**\n * Attempts to resolve linked packages using various fallback strategies\n */\nexport async function resolveLinkedPackage<T>(\n packageName: string,\n subPath: string,\n): Promise<T | null> {\n // Try Node.js suggested paths first\n let result = await tryNodeSuggestedPaths<T>(packageName, subPath);\n if (result) return result;\n\n // Try import.meta.resolve\n result = await tryImportMetaResolve<T>(packageName, subPath);\n if (result) return result;\n\n // Try symlink resolution\n const symlinkPaths = await resolveSymlinkedPaths(packageName, subPath);\n result = await tryWorkspacePatterns<T>(symlinkPaths);\n if (result) return result;\n\n // Try common workspace patterns as final fallback\n const commonPaths = getCommonWorkspacePaths(packageName, subPath);\n result = await tryWorkspacePatterns<T>(commonPaths);\n if (result) return result;\n\n return null;\n}\n","import type {\n ProcessorFactoryBuilder,\n SubgraphClass,\n} from \"@powerhousedao/reactor-api\";\nimport type {\n DocumentModelModule,\n UpgradeManifest,\n} from \"@powerhousedao/shared/document-model\";\nimport { childLogger } from \"document-model\";\nimport { execSync } from \"node:child_process\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolveLinkedPackage } from \"./import-resolver.js\";\n\n// Define the expected module export structures\ntype DocumentModelsExport = Record<string, DocumentModelModule>;\ntype SubgraphsExport = Record<string, Record<string, SubgraphClass>>;\ntype ProcessorsExport = {\n processorFactory?: ProcessorFactoryBuilder;\n processorFactoryLegacy?: ProcessorFactoryBuilder;\n};\n\nconst _logger = childLogger([\"reactor-api\", \"packages/util\"]);\n\nexport const installPackages = (packages: string[]): Promise<void> => {\n for (const packageName of packages) {\n execSync(`ph install ${packageName}`);\n }\n return Promise.resolve();\n};\n\nexport const readManifest = () => {\n const manifest = execSync(`ph manifest`).toString();\n return manifest;\n};\n\n/**\n * Tries to import document models from a package. This function cannot throw.\n */\nexport async function loadDocumentModels(\n packageName: string,\n): Promise<DocumentModelsExport | null> {\n return loadDependency(packageName, \"document-models\");\n}\n\n/**\n * Tries to import subgraphs from a package. This function cannot throw.\n */\nexport async function loadSubgraphs(\n packageName: string,\n): Promise<SubgraphsExport | null> {\n return loadDependency(packageName, \"subgraphs\");\n}\n\n/**\n * Tries to import processors from a package. This function cannot throw.\n */\nexport async function loadProcessors(\n packageName: string,\n): Promise<ProcessorsExport | null> {\n return loadDependency(packageName, \"processors\");\n}\n\n/**\n * Generic dependency loader - tries to import a dependency from a package. This function cannot throw.\n * Returns null if the dependency cannot be loaded.\n */\nasync function loadDependency<T = unknown>(\n packageName: string,\n subPath: string,\n): Promise<T> {\n // A local package is identified by an absolute path, which has to become a\n // file:// URL: the ESM loader reads the drive letter in a Windows path as a\n // URL scheme.\n const fullPath = path.isAbsolute(packageName)\n ? pathToFileURL(path.join(packageName, subPath)).href\n : `${packageName}/${subPath}`;\n\n // Try the standard import first\n try {\n // vite does not support this, but that's okay as we have provided the\n // vite-loader for this purpose\n\n const module = (await import(/* @vite-ignore */ fullPath)) as T;\n return module;\n } catch (e) {\n // Handle module not found errors with fallback resolution.\n // ERR_UNSUPPORTED_ESM_URL_SCHEME joins the list because a directory\n // specifier that is a plain path fails with it on Windows where POSIX\n // reports ERR_UNSUPPORTED_DIR_IMPORT.\n if (\n e instanceof Error &&\n \"code\" in e &&\n (e.code === \"ERR_MODULE_NOT_FOUND\" ||\n e.code === \"ERR_UNSUPPORTED_DIR_IMPORT\" ||\n e.code === \"ERR_UNSUPPORTED_ESM_URL_SCHEME\")\n ) {\n const result = await resolveLinkedPackage<T>(packageName, subPath);\n if (result) return result;\n }\n throw e;\n }\n}\n\nfunction isUpgradeManifest(\n value: unknown,\n): value is UpgradeManifest<readonly number[]> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"documentType\" in value &&\n \"supportedVersions\" in value &&\n \"upgrades\" in value\n );\n}\n\n/**\n * Collects upgrade manifests from a package's document-models namespace.\n * Handles both the aggregate `upgradeManifests` array export and individual\n * manifest exports; dedupes by documentType.\n */\nexport function extractUpgradeManifests(\n namespace: Record<string, unknown>,\n): UpgradeManifest<readonly number[]>[] {\n const manifests = new Map<string, UpgradeManifest<readonly number[]>>();\n const add = (value: unknown) => {\n if (isUpgradeManifest(value)) {\n manifests.set(value.documentType, value);\n }\n };\n for (const value of Object.values(namespace)) {\n if (Array.isArray(value)) {\n value.forEach(add);\n } else {\n add(value);\n }\n }\n return Array.from(manifests.values());\n}\n\nexport function debounce<T extends unknown[], R>(\n func: (...args: T) => Promise<R>,\n delay = 250,\n) {\n let timer: number;\n return (immediate = false, ...args: T) => {\n if (timer) {\n clearTimeout(timer);\n }\n return new Promise<R>((resolve, reject) => {\n if (immediate) {\n func(...args)\n .then(resolve)\n .catch(reject);\n } else {\n timer = setTimeout(() => {\n func(...args)\n .then(resolve)\n .catch(reject);\n }, delay) as unknown as number;\n }\n });\n };\n}\n\nexport function isSubpath(parent: string, dir: string) {\n const relative = path.relative(parent, dir);\n return relative && !relative.startsWith(\"..\") && !path.isAbsolute(relative);\n}\n","import type {\n GqlDocument,\n GqlDriveDocument,\n GqlOperation,\n SubgraphClass,\n} from \"@powerhousedao/reactor-api\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type {\n Operation,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { BaseSubgraph } from \"./base-subgraph.js\";\n\nexport function isSubgraphClass(\n candidate: unknown,\n): candidate is SubgraphClass {\n if (typeof candidate !== \"function\") return false;\n\n let proto: unknown = Object.getPrototypeOf(candidate);\n while (proto) {\n if (Object.prototype.isPrototypeOf.call(proto, BaseSubgraph)) return true;\n\n proto = Object.getPrototypeOf(proto);\n }\n\n return false;\n}\n\nexport function buildGraphqlOperations(\n operations: Operation[],\n skip: number,\n first: number,\n): GqlOperation[] {\n return operations.slice(skip, skip + first).map(buildGraphqlOperation);\n}\n\nexport function buildGraphqlOperation(operation: Operation): GqlOperation {\n const signer = operation.action.context?.signer;\n return {\n id: operation.id ?? \"\",\n type: operation.action.type,\n index: operation.index,\n timestampUtcMs: operation.timestampUtcMs,\n hash: operation.hash,\n skip: operation.skip,\n inputText:\n typeof operation.action.input === \"string\"\n ? operation.action.input\n : JSON.stringify(operation.action.input),\n error: operation.error,\n context: {\n signer: signer\n ? {\n user: signer.user,\n app: signer.app,\n signatures: signer.signatures.map((sig) =>\n Array.isArray(sig) ? sig.join(\", \") : sig,\n ),\n }\n : undefined,\n },\n };\n}\n\nexport function buildGraphQlDocument(doc: PHDocument): GqlDocument {\n // Return full state with all scopes (auth, document, global, local)\n // This matches the ReactorSubgraph pattern in adapters.ts\n const state = doc.state;\n const initialState = doc.initialState;\n // For stateJSON, use global state for backward compatibility\n const globalState = \"global\" in doc.state ? doc.state.global : {};\n return {\n id: doc.header.id,\n name: doc.header.name,\n documentType: doc.header.documentType,\n revision: doc.header.revision.global || 0,\n createdAtUtcIso: doc.header.createdAtUtcIso,\n lastModifiedAtUtcIso: doc.header.lastModifiedAtUtcIso,\n operations: [],\n stateJSON: globalState as JSON,\n state,\n initialState,\n };\n}\n\nexport function buildGraphQlDriveDocument(\n doc: DocumentDriveDocument,\n): GqlDriveDocument {\n const gqlDoc = buildGraphQlDocument(doc);\n return {\n ...gqlDoc,\n meta: {\n preferredEditor: doc.header.meta?.preferredEditor,\n },\n slug: doc.header.slug,\n state: doc.state.global,\n initialState: doc.state.global,\n };\n}\n","// The pieces a package ships, located on disk for a host that never runs them.\n\n// Only the list module is ever imported here: it holds no piece code, and a\n// piece itself runs in a forked worker, handed the path this reports.\nimport { packageJsonExports } from \"@powerhousedao/shared/clis/constants\";\nimport type { ILogger } from \"document-model\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { PackagePiece, PackagePieceEntry } from \"./types.js\";\n\n/** The sub-entry every loader asks a package for its pieces through. */\nexport const PIECES_SUBPATH = \"pieces\";\n\n// Where the node build leaves the list, read from the export map a generated\n// package ships so the build and the host cannot disagree about the path.\nexport const BUILT_PIECE_LIST = packageJsonExports[\"./pieces\"].node;\n\n/** Where a package keeps its piece sources, for telling unbuilt from absent. */\nexport const PIECE_SOURCE_LIST = join(PIECES_SUBPATH, \"index.ts\");\n\n/** The nearest enclosing package.json, which `exports` usually hides. */\nexport function packageRootOf(dir: string): string | undefined {\n let current = dir;\n while (!existsSync(join(current, \"package.json\"))) {\n const parent = dirname(current);\n if (parent === current) return undefined;\n current = parent;\n }\n return current;\n}\n\nexport interface PieceListLocation {\n /** Absolute; a declared entry is relative to it. */\n root: string;\n /** Absolute path of the list module, built or not. */\n listPath: string;\n}\n\n// Resolved from this module first, then from the host's own dependencies,\n// which is where document models are found too; the first error is the one kept.\nfunction resolvePieceList(specifier: string, hostDir: string): string {\n try {\n return fileURLToPath(import.meta.resolve(specifier));\n } catch (error) {\n try {\n return createRequire(join(hostDir, \"package.json\")).resolve(specifier);\n } catch {\n throw error;\n }\n }\n}\n\n// Where a package's piece list sits and what its entries are relative to. A\n// path identifier is its own root; a name resolves as a host would import it.\nexport function pieceListLocation(\n identifier: string,\n hostDir = process.cwd(),\n): PieceListLocation {\n if (isAbsolute(identifier)) {\n return { root: identifier, listPath: join(identifier, BUILT_PIECE_LIST) };\n }\n // Left to throw, with the ESM resolver's error codes: they're what the\n // package manager reads a miss from.\n const listPath = resolvePieceList(`${identifier}/${PIECES_SUBPATH}`, hostDir);\n const root = packageRootOf(dirname(listPath));\n if (!root) {\n throw new Error(`No package.json above ${listPath}`);\n }\n return { root, listPath };\n}\n\n// A piece's version is its package's, so it is read from the package root.\nexport function packageVersionAt(root: string): string | undefined {\n try {\n const pkg = JSON.parse(\n readFileSync(join(root, \"package.json\"), \"utf8\"),\n ) as { version?: unknown };\n return typeof pkg.version === \"string\" && pkg.version !== \"\"\n ? pkg.version\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n// A declared piece counts only once its code is on disk: one nobody built is\n// reported rather than dropped, because a block type names it either way.\nexport function locatePieces(\n declared: readonly PackagePiece[],\n context: {\n root: string;\n identifier: string;\n logger: ILogger;\n version: string;\n },\n): PackagePieceEntry[] {\n const { root, identifier, logger, version } = context;\n const located: PackagePieceEntry[] = [];\n for (const piece of declared) {\n const where = piece.entry ?? piece.bundle;\n if (typeof where !== \"string\" || where === \"\") {\n // Every name goes through a logger value: `@`-prefixed tokens are\n // substituted, so a scoped one printed inline comes out as null/pack.\n logger.warn(\n \"Piece @piece of @pkg declares neither a bundle nor an entry\",\n piece.name,\n identifier,\n );\n continue;\n }\n const path = isAbsolute(where) ? where : join(root, where);\n const present = piece.entry\n ? existsSync(path)\n : existsSync(join(path, \"package.json\"));\n if (!present) {\n logger.warn(\n \"Piece @piece of @pkg is declared but not built at @path\",\n piece.name,\n identifier,\n path,\n );\n continue;\n }\n located.push({\n name: piece.name,\n version,\n ...(piece.entry ? { entryPath: path } : { bundleDir: path }),\n });\n }\n return located;\n}\n\n// A package's `pieces` array, however the list module was obtained.\nfunction declaredPieces(\n module: unknown,\n identifier: string,\n logger: ILogger,\n): PackagePiece[] | undefined {\n const namespace = (module ?? {}) as { pieces?: unknown; default?: unknown };\n const declared = namespace.pieces ?? namespace.default;\n if (!Array.isArray(declared)) {\n logger.warn(\n 'The pieces list of @pkg exports no \"pieces\" array; it contributes none',\n identifier,\n );\n return undefined;\n }\n return declared as PackagePiece[];\n}\n\n// The same list, served by a registry rather than read off a disk. Nothing is\n// checked for existence here: the CDN is asked when the piece is run.\n\n// `entry` is relative to the package root while the CDN serves beneath\n// `dist/`, so that prefix comes off before the base is applied.\nexport function piecesFromCdnList(\n module: unknown,\n baseUrl: string,\n identifier: string,\n logger: ILogger,\n version: string,\n): PackagePieceEntry[] {\n const declared = declaredPieces(module, identifier, logger);\n if (!declared) return [];\n const located: PackagePieceEntry[] = [];\n for (const piece of declared) {\n const where = piece.entry ?? piece.bundle;\n if (typeof where !== \"string\" || where === \"\") {\n logger.warn(\n \"Piece @piece of @pkg declares neither a bundle nor an entry\",\n piece.name,\n identifier,\n );\n continue;\n }\n located.push({\n name: piece.name,\n version,\n entryUrl: `${baseUrl}${where.replace(/^dist\\/node\\/pieces\\//, \"\")}`,\n });\n }\n return located;\n}\n\n// What a loaded list module contributes. A module without a `pieces` array is\n// not a list, and saying so beats reporting the package as shipping none.\nexport function piecesFromListModule(\n module: unknown,\n context: { root: string; identifier: string; logger: ILogger },\n): PackagePieceEntry[] {\n const namespace = (module ?? {}) as { pieces?: unknown; default?: unknown };\n const declared = namespace.pieces ?? namespace.default;\n if (!Array.isArray(declared)) {\n context.logger.warn(\n 'The pieces list of @pkg exports no \"pieces\" array; it contributes none',\n context.identifier,\n );\n return [];\n }\n const version = packageVersionAt(context.root);\n if (!version) {\n context.logger.warn(\n \"@pkg has no version in @root/package.json, and a piece takes its package's version; its pieces contribute none\",\n context.identifier,\n context.root,\n );\n return [];\n }\n return locatePieces(declared as PackagePiece[], { ...context, version });\n}\n"],"names":[],"mappings":"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","debug_id":"0af7e584-ef45-5330-b69b-706629bea4c2"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __exportAll = (all, no_symbols) => {
|
|
5
|
+
let target = {};
|
|
6
|
+
for (var name in all) __defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
11
|
+
return target;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { __exportAll as t };
|
|
15
|
+
!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]="e3b80eba-208e-51a9-b437-5ac76accf5d0")}catch(e){}}();
|
|
16
|
+
//# debugId=e3b80eba-208e-51a9-b437-5ac76accf5d0
|
|
@@ -0,0 +1,52 @@
|
|
|
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]="b96f00d4-5192-57bc-b435-7cc0f7c0f5c8")}catch(e){}}();
|
|
3
|
+
import { childLogger } from "document-model";
|
|
4
|
+
//#region src/graphql/gateway/path-normalize.ts
|
|
5
|
+
/**
|
|
6
|
+
* Normalises a route path for path-to-regexp v8:
|
|
7
|
+
* - Collapses duplicate slashes (e.g. "//explorer" → "/explorer")
|
|
8
|
+
* - Converts legacy optional-param syntax "/:param?" → "{/:param}". The
|
|
9
|
+
* slash must move inside the group: in p-r v8 a group whose content
|
|
10
|
+
* begins with "/" is what makes the slash and the parameter optional
|
|
11
|
+
* together, while a literal "/" left in front of the group compiles to
|
|
12
|
+
* a pattern that matches nothing (and v8 rejects a bare ":param?").
|
|
13
|
+
*
|
|
14
|
+
* Shared by both http adapters so registry dispatch matches the same path
|
|
15
|
+
* shapes regardless of which framework is in use.
|
|
16
|
+
*/
|
|
17
|
+
function normalizePath(path) {
|
|
18
|
+
return path.replace(/\/+/g, "/").replace(/\/:(\w+)\?/g, "{/:$1}");
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/graphql/gateway/run-node-handler.ts
|
|
22
|
+
const logger = childLogger(["reactor-api", "node-route"]);
|
|
23
|
+
/**
|
|
24
|
+
* Runs a node route handler without awaiting it. A throw or rejection is
|
|
25
|
+
* logged and answered with a 500, or ends the socket if headers already went
|
|
26
|
+
* out; it never reaches the process as an unhandled rejection.
|
|
27
|
+
*/
|
|
28
|
+
function runNodeHandler(handler, req, res, body) {
|
|
29
|
+
const fail = (err) => {
|
|
30
|
+
logger.error("Node route handler failed for @method @url: @error", req.method, req.url, err);
|
|
31
|
+
if (res.headersSent) {
|
|
32
|
+
res.destroy();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
res.statusCode = 500;
|
|
36
|
+
res.setHeader("Content-Type", "application/json");
|
|
37
|
+
res.end(JSON.stringify({ error: "Internal error" }));
|
|
38
|
+
};
|
|
39
|
+
let result;
|
|
40
|
+
try {
|
|
41
|
+
result = handler(req, res, body);
|
|
42
|
+
} catch (err) {
|
|
43
|
+
fail(err);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (result) result.catch(fail);
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { normalizePath as n, runNodeHandler as t };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=run-node-handler-CQjyjOuN.mjs.map
|
|
52
|
+
//# debugId=b96f00d4-5192-57bc-b435-7cc0f7c0f5c8
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-node-handler-CQjyjOuN.mjs","sources":["../src/graphql/gateway/path-normalize.ts","../src/graphql/gateway/run-node-handler.ts"],"sourcesContent":["/**\n * Normalises a route path for path-to-regexp v8:\n * - Collapses duplicate slashes (e.g. \"//explorer\" → \"/explorer\")\n * - Converts legacy optional-param syntax \"/:param?\" → \"{/:param}\". The\n * slash must move inside the group: in p-r v8 a group whose content\n * begins with \"/\" is what makes the slash and the parameter optional\n * together, while a literal \"/\" left in front of the group compiles to\n * a pattern that matches nothing (and v8 rejects a bare \":param?\").\n *\n * Shared by both http adapters so registry dispatch matches the same path\n * shapes regardless of which framework is in use.\n */\nexport function normalizePath(path: string): string {\n return path.replace(/\\/+/g, \"/\").replace(/\\/:(\\w+)\\?/g, \"{/:$1}\");\n}\n","import { childLogger } from \"document-model\";\nimport type http from \"node:http\";\n\nconst logger = childLogger([\"reactor-api\", \"node-route\"]);\n\nexport type NodeHandler = (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body?: unknown,\n) => void | Promise<void>;\n\n/**\n * Runs a node route handler without awaiting it. A throw or rejection is\n * logged and answered with a 500, or ends the socket if headers already went\n * out; it never reaches the process as an unhandled rejection.\n */\nexport function runNodeHandler(\n handler: NodeHandler,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: unknown,\n): void {\n const fail = (err: unknown): void => {\n logger.error(\n \"Node route handler failed for @method @url: @error\",\n req.method,\n req.url,\n err,\n );\n if (res.headersSent) {\n res.destroy();\n return;\n }\n res.statusCode = 500;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({ error: \"Internal error\" }));\n };\n\n let result: void | Promise<void>;\n try {\n result = handler(req, res, body);\n } catch (err) {\n fail(err);\n return;\n }\n if (result) {\n result.catch(fail);\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAYA,SAAgB,cAAc,MAAsB;CAClD,OAAO,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,QAAQ,eAAe,QAAQ;AAClE;;;ACXA,MAAM,SAAS,YAAY,CAAC,eAAe,YAAY,CAAC;;;;;;AAaxD,SAAgB,eACd,SACA,KACA,KACA,MACM;CACN,MAAM,QAAQ,QAAuB;EACnC,OAAO,MACL,sDACA,IAAI,QACJ,IAAI,KACJ,GACF;EACA,IAAI,IAAI,aAAa;GACnB,IAAI,QAAQ;GACZ;EACF;EACA,IAAI,aAAa;EACjB,IAAI,UAAU,gBAAgB,kBAAkB;EAChD,IAAI,IAAI,KAAK,UAAU,EAAE,OAAO,iBAAiB,CAAC,CAAC;CACrD;CAEA,IAAI;CACJ,IAAI;EACF,SAAS,QAAQ,KAAK,KAAK,IAAI;CACjC,SAAS,KAAK;EACZ,KAAK,GAAG;EACR;CACF;CACA,IAAI,QACF,OAAO,MAAM,IAAI;AAErB","debug_id":"b96f00d4-5192-57bc-b435-7cc0f7c0f5c8"}
|
|
@@ -25,15 +25,15 @@ type NextLoad = (url: string, context: LoadContext) => Promise<LoadResult>;
|
|
|
25
25
|
/**
|
|
26
26
|
* Resolve hook: resolves relative specifiers against HTTP/HTTPS parent URLs.
|
|
27
27
|
*/
|
|
28
|
-
declare function resolve(specifier: string, context: ResolveContext, nextResolve: NextResolve): Promise<ResolveResult>;
|
|
28
|
+
export declare function resolve(specifier: string, context: ResolveContext, nextResolve: NextResolve): Promise<ResolveResult>;
|
|
29
29
|
/**
|
|
30
30
|
* Load hook: fetches module source from HTTP/HTTPS URLs.
|
|
31
31
|
*/
|
|
32
|
-
declare function load(url: string, context: LoadContext, nextLoad: NextLoad): Promise<LoadResult>;
|
|
32
|
+
export declare function load(url: string, context: LoadContext, nextLoad: NextLoad): Promise<LoadResult>;
|
|
33
33
|
/**
|
|
34
34
|
* Path to this hooks file for use with node:module register()
|
|
35
35
|
*/
|
|
36
|
-
declare const httpsHooksPath: string;
|
|
36
|
+
export declare const httpsHooksPath: string;
|
|
37
37
|
//#endregion
|
|
38
|
-
export {
|
|
38
|
+
export {};
|
|
39
39
|
//# sourceMappingURL=https-hooks.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"https-hooks.d.mts","names":[],"sources":["../../../src/packages/https-hooks.mts"],"mappings":";;;;;KASK
|
|
1
|
+
{"version":3,"file":"https-hooks.d.mts","names":[],"sources":["../../../src/packages/https-hooks.mts"],"mappings":";;;;;KASK;EAAmB;EAAoB;;KACvC;EACH;EACA;EACA;;KAEG,eACH,mBACA,SAAS,mBACN,QAAQ;KAER;EAAgB;;KAChB;EAAe;EAAgB;EAAwB;;KACvD,YAAY,aAAa,SAAS,gBAAgB,QAAQ;;;;wBAKzC,QACpB,mBACA,SAAS,gBACT,aAAa,cACZ,QAAQ;;;;wBAgEW,KACpB,aACA,SAAS,aACT,UAAU,WACT,QAAQ;;;;qBAoFE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
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]="
|
|
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]="8149a6c4-bab0-57e3-a471-cfc77d529bbf")}catch(e){}}();
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { get } from "node:http";
|
|
5
5
|
import { get as get$1 } from "node:https";
|
|
@@ -99,4 +99,4 @@ const httpsHooksPath = import.meta.url;
|
|
|
99
99
|
export { httpsHooksPath, load, resolve };
|
|
100
100
|
|
|
101
101
|
//# sourceMappingURL=https-hooks.mjs.map
|
|
102
|
-
//# debugId=
|
|
102
|
+
//# debugId=8149a6c4-bab0-57e3-a471-cfc77d529bbf
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"https-hooks.mjs","sources":["../../../src/packages/https-hooks.mts"],"sourcesContent":["import { get as httpGet } from \"node:http\";\nimport { get } from \"node:https\";\nimport { pathToFileURL } from \"node:url\";\n\n/**\n * Node.js module loader hooks that enable importing from HTTP/HTTPS URLs.\n * See: https://nodejs.org/docs/latest-v24.x/api/module.html#import-from-https\n */\n\ntype ResolveContext = { parentURL?: string; conditions?: string[] };\ntype ResolveResult = {\n url: string;\n shortCircuit?: boolean;\n format?: string;\n};\ntype NextResolve = (\n specifier: string,\n context: ResolveContext,\n) => Promise<ResolveResult>;\n\ntype LoadContext = { format?: string };\ntype LoadResult = { format: string; shortCircuit?: boolean; source: string };\ntype NextLoad = (url: string, context: LoadContext) => Promise<LoadResult>;\n\n/**\n * Resolve hook: resolves relative specifiers against HTTP/HTTPS parent URLs.\n */\nexport async function resolve(\n specifier: string,\n context: ResolveContext,\n nextResolve: NextResolve,\n): Promise<ResolveResult> {\n const { parentURL } = context;\n\n // If the specifier is already an HTTP(S) URL, resolve it directly\n if (specifier.startsWith(\"https://\") || specifier.startsWith(\"http://\")) {\n return { url: specifier, shortCircuit: true, format: \"module\" };\n }\n\n // If the parent is an HTTP(S) URL and specifier is relative, resolve against it.\n // Only handle relative specifiers (./ or ../), not bare package specifiers.\n if (\n parentURL &&\n (parentURL.startsWith(\"https://\") || parentURL.startsWith(\"http://\")) &&\n (specifier.startsWith(\"./\") || specifier.startsWith(\"../\"))\n ) {\n const resolved = new URL(specifier, parentURL).href;\n return { url: resolved, shortCircuit: true, format: \"module\" };\n }\n\n // Bare specifiers from HTTP modules need a node_modules root to resolve\n // against. Under pnpm's strict isolation the deps a registry-built bundle\n // needs split into two classes:\n // - Peer deps the *consumer* declared (react, react-dom, graphql, …) —\n // live at the consumer project root.\n // - Things reactor-api keeps external by design (the reactor-api package\n // itself, for class identity; internal helpers) — live in reactor-api's\n // own tree.\n // Neither root sees the other under strict mode, so try the consumer first\n // (its declared peers win on version) and fall back to reactor-api's tree.\n //\n // At this point: specifier is not an http(s):// URL (branch 1) and not\n // relative (branch 2). Only redirect bare package specifiers; let absolute\n // paths and other URL schemes (e.g. \"node:fs\", \"file://…\") fall through.\n if (\n parentURL &&\n (parentURL.startsWith(\"https://\") || parentURL.startsWith(\"http://\"))\n ) {\n const isBareSpecifier =\n !specifier.startsWith(\"/\") && !/^[a-z][a-z0-9+.-]*:/i.test(specifier);\n if (isBareSpecifier) {\n const consumerRoot = pathToFileURL(process.cwd() + \"/\").href;\n try {\n return await nextResolve(specifier, {\n ...context,\n parentURL: consumerRoot,\n });\n } catch (e) {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n if (code !== \"ERR_MODULE_NOT_FOUND\") throw e;\n return nextResolve(specifier, {\n ...context,\n parentURL: import.meta.url,\n });\n }\n }\n }\n\n // Let Node.js handle all other specifiers\n return nextResolve(specifier, context);\n}\n\n/**\n * Load hook: fetches module source from HTTP/HTTPS URLs.\n */\nexport async function load(\n url: string,\n context: LoadContext,\n nextLoad: NextLoad,\n): Promise<LoadResult> {\n // Handle HTTPS URLs\n if (url.startsWith(\"https://\")) {\n const source = await fetchModule(url, get);\n return {\n format: \"module\",\n shortCircuit: true,\n source: patchCreateRequire(source),\n };\n }\n\n // Handle HTTP URLs (for local development)\n if (url.startsWith(\"http://\")) {\n const source = await fetchModule(url, httpGet);\n return {\n format: \"module\",\n shortCircuit: true,\n source: patchCreateRequire(source),\n };\n }\n\n // Let Node.js handle all other URLs\n return nextLoad(url, context);\n}\n\n/**\n * Rewrite `createRequire(import.meta.url)` in HTTP-loaded modules so that\n * `createRequire` receives a local file URL instead of an HTTP URL it cannot handle.\n *\n * The base is baked in at hook time as a string literal. Injecting a live\n * `process.cwd()` call into the module source (the previous approach) crashes\n * with \"process.cwd is not a function\": HTTP-loaded modules execute in the\n * module-customization realm, which has no full `process`. This hook itself\n * runs where `process.cwd()` works, so we resolve the base here and embed the\n * resulting file URL as a literal — no runtime `process` access in the loaded\n * module. Any package whose bundle contains `createRequire(import.meta.url)`\n * (common CJS interop) failed to load before this.\n */\nfunction patchCreateRequire(source: string): string {\n const requireBase = pathToFileURL(process.cwd() + \"/\").href;\n return source.replace(\n /createRequire\\(import\\.meta\\.url\\)/g,\n `createRequire(${JSON.stringify(requireBase)})`,\n );\n}\n\nfunction fetchModule(\n url: string,\n getter: typeof get | typeof httpGet,\n): Promise<string> {\n return new Promise((resolve, reject) => {\n getter(url, (res) => {\n // Handle redirects\n if (\n res.statusCode &&\n res.statusCode >= 300 &&\n res.statusCode < 400 &&\n res.headers.location\n ) {\n const redirectUrl = res.headers.location;\n const redirectGetter = redirectUrl.startsWith(\"https://\")\n ? get\n : httpGet;\n fetchModule(redirectUrl, redirectGetter).then(resolve).catch(reject);\n return;\n }\n\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to fetch ${url}: ${res.statusCode}`));\n return;\n }\n\n let data = \"\";\n res.setEncoding(\"utf8\");\n res.on(\"data\", (chunk) => (data += chunk));\n res.on(\"end\", () => resolve(data));\n res.on(\"error\", reject);\n }).on(\"error\", reject);\n });\n}\n\n/**\n * Path to this hooks file for use with node:module register()\n */\nexport const httpsHooksPath: string = import.meta.url;\n"],"names":["get","httpGet"],"mappings":";;;;;;;;;AA2BA,eAAsB,QACpB,WACA,SACA,aACwB;CACxB,MAAM,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"https-hooks.mjs","sources":["../../../src/packages/https-hooks.mts"],"sourcesContent":["import { get as httpGet } from \"node:http\";\nimport { get } from \"node:https\";\nimport { pathToFileURL } from \"node:url\";\n\n/**\n * Node.js module loader hooks that enable importing from HTTP/HTTPS URLs.\n * See: https://nodejs.org/docs/latest-v24.x/api/module.html#import-from-https\n */\n\ntype ResolveContext = { parentURL?: string; conditions?: string[] };\ntype ResolveResult = {\n url: string;\n shortCircuit?: boolean;\n format?: string;\n};\ntype NextResolve = (\n specifier: string,\n context: ResolveContext,\n) => Promise<ResolveResult>;\n\ntype LoadContext = { format?: string };\ntype LoadResult = { format: string; shortCircuit?: boolean; source: string };\ntype NextLoad = (url: string, context: LoadContext) => Promise<LoadResult>;\n\n/**\n * Resolve hook: resolves relative specifiers against HTTP/HTTPS parent URLs.\n */\nexport async function resolve(\n specifier: string,\n context: ResolveContext,\n nextResolve: NextResolve,\n): Promise<ResolveResult> {\n const { parentURL } = context;\n\n // If the specifier is already an HTTP(S) URL, resolve it directly\n if (specifier.startsWith(\"https://\") || specifier.startsWith(\"http://\")) {\n return { url: specifier, shortCircuit: true, format: \"module\" };\n }\n\n // If the parent is an HTTP(S) URL and specifier is relative, resolve against it.\n // Only handle relative specifiers (./ or ../), not bare package specifiers.\n if (\n parentURL &&\n (parentURL.startsWith(\"https://\") || parentURL.startsWith(\"http://\")) &&\n (specifier.startsWith(\"./\") || specifier.startsWith(\"../\"))\n ) {\n const resolved = new URL(specifier, parentURL).href;\n return { url: resolved, shortCircuit: true, format: \"module\" };\n }\n\n // Bare specifiers from HTTP modules need a node_modules root to resolve\n // against. Under pnpm's strict isolation the deps a registry-built bundle\n // needs split into two classes:\n // - Peer deps the *consumer* declared (react, react-dom, graphql, …) —\n // live at the consumer project root.\n // - Things reactor-api keeps external by design (the reactor-api package\n // itself, for class identity; internal helpers) — live in reactor-api's\n // own tree.\n // Neither root sees the other under strict mode, so try the consumer first\n // (its declared peers win on version) and fall back to reactor-api's tree.\n //\n // At this point: specifier is not an http(s):// URL (branch 1) and not\n // relative (branch 2). Only redirect bare package specifiers; let absolute\n // paths and other URL schemes (e.g. \"node:fs\", \"file://…\") fall through.\n if (\n parentURL &&\n (parentURL.startsWith(\"https://\") || parentURL.startsWith(\"http://\"))\n ) {\n const isBareSpecifier =\n !specifier.startsWith(\"/\") && !/^[a-z][a-z0-9+.-]*:/i.test(specifier);\n if (isBareSpecifier) {\n const consumerRoot = pathToFileURL(process.cwd() + \"/\").href;\n try {\n return await nextResolve(specifier, {\n ...context,\n parentURL: consumerRoot,\n });\n } catch (e) {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n if (code !== \"ERR_MODULE_NOT_FOUND\") throw e;\n return nextResolve(specifier, {\n ...context,\n parentURL: import.meta.url,\n });\n }\n }\n }\n\n // Let Node.js handle all other specifiers\n return nextResolve(specifier, context);\n}\n\n/**\n * Load hook: fetches module source from HTTP/HTTPS URLs.\n */\nexport async function load(\n url: string,\n context: LoadContext,\n nextLoad: NextLoad,\n): Promise<LoadResult> {\n // Handle HTTPS URLs\n if (url.startsWith(\"https://\")) {\n const source = await fetchModule(url, get);\n return {\n format: \"module\",\n shortCircuit: true,\n source: patchCreateRequire(source),\n };\n }\n\n // Handle HTTP URLs (for local development)\n if (url.startsWith(\"http://\")) {\n const source = await fetchModule(url, httpGet);\n return {\n format: \"module\",\n shortCircuit: true,\n source: patchCreateRequire(source),\n };\n }\n\n // Let Node.js handle all other URLs\n return nextLoad(url, context);\n}\n\n/**\n * Rewrite `createRequire(import.meta.url)` in HTTP-loaded modules so that\n * `createRequire` receives a local file URL instead of an HTTP URL it cannot handle.\n *\n * The base is baked in at hook time as a string literal. Injecting a live\n * `process.cwd()` call into the module source (the previous approach) crashes\n * with \"process.cwd is not a function\": HTTP-loaded modules execute in the\n * module-customization realm, which has no full `process`. This hook itself\n * runs where `process.cwd()` works, so we resolve the base here and embed the\n * resulting file URL as a literal — no runtime `process` access in the loaded\n * module. Any package whose bundle contains `createRequire(import.meta.url)`\n * (common CJS interop) failed to load before this.\n */\nfunction patchCreateRequire(source: string): string {\n const requireBase = pathToFileURL(process.cwd() + \"/\").href;\n return source.replace(\n /createRequire\\(import\\.meta\\.url\\)/g,\n `createRequire(${JSON.stringify(requireBase)})`,\n );\n}\n\nfunction fetchModule(\n url: string,\n getter: typeof get | typeof httpGet,\n): Promise<string> {\n return new Promise((resolve, reject) => {\n getter(url, (res) => {\n // Handle redirects\n if (\n res.statusCode &&\n res.statusCode >= 300 &&\n res.statusCode < 400 &&\n res.headers.location\n ) {\n const redirectUrl = res.headers.location;\n const redirectGetter = redirectUrl.startsWith(\"https://\")\n ? get\n : httpGet;\n fetchModule(redirectUrl, redirectGetter).then(resolve).catch(reject);\n return;\n }\n\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to fetch ${url}: ${res.statusCode}`));\n return;\n }\n\n let data = \"\";\n res.setEncoding(\"utf8\");\n res.on(\"data\", (chunk) => (data += chunk));\n res.on(\"end\", () => resolve(data));\n res.on(\"error\", reject);\n }).on(\"error\", reject);\n });\n}\n\n/**\n * Path to this hooks file for use with node:module register()\n */\nexport const httpsHooksPath: string = import.meta.url;\n"],"names":["get","httpGet"],"mappings":";;;;;;;;;AA2BA,eAAsB,QACpB,WACA,SACA,aACwB;CACxB,MAAM,EAAE,cAAc;CAGtB,IAAI,UAAU,WAAW,UAAU,KAAK,UAAU,WAAW,SAAS,GACpE,OAAO;EAAE,KAAK;EAAW,cAAc;EAAM,QAAQ;CAAS;CAKhE,IACE,cACC,UAAU,WAAW,UAAU,KAAK,UAAU,WAAW,SAAS,OAClE,UAAU,WAAW,IAAI,KAAK,UAAU,WAAW,KAAK,IAGzD,OAAO;EAAE,KADQ,IAAI,IAAI,WAAW,SAAS,CAAC,CAAC;EACvB,cAAc;EAAM,QAAQ;CAAS;CAiB/D,IACE,cACC,UAAU,WAAW,UAAU,KAAK,UAAU,WAAW,SAAS,IAGjE;MAAA,CAAC,UAAU,WAAW,GAAG,KAAK,CAAC,uBAAuB,KAAK,SAAS,GACjD;GACnB,MAAM,eAAe,cAAc,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC;GACxD,IAAI;IACF,OAAO,MAAM,YAAY,WAAW;KAClC,GAAG;KACH,WAAW;IACb,CAAC;GACH,SAAS,GAAG;IAEV,IADc,GAAyC,SAC1C,wBAAwB,MAAM;IAC3C,OAAO,YAAY,WAAW;KAC5B,GAAG;KACH,WAAW,YAAY;IACzB,CAAC;GACH;EACF;;CAIF,OAAO,YAAY,WAAW,OAAO;AACvC;;;;AAKA,eAAsB,KACpB,KACA,SACA,UACqB;CAErB,IAAI,IAAI,WAAW,UAAU,GAE3B,OAAO;EACL,QAAQ;EACR,cAAc;EACd,QAAQ,mBAAmB,MAJR,YAAY,KAAKA,KAAG,CAIN;CACnC;CAIF,IAAI,IAAI,WAAW,SAAS,GAE1B,OAAO;EACL,QAAQ;EACR,cAAc;EACd,QAAQ,mBAAmB,MAJR,YAAY,KAAKC,GAAO,CAIV;CACnC;CAIF,OAAO,SAAS,KAAK,OAAO;AAC9B;;;;;;;;;;;;;;AAeA,SAAS,mBAAmB,QAAwB;CAClD,MAAM,cAAc,cAAc,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC;CACvD,OAAO,OAAO,QACZ,uCACA,iBAAiB,KAAK,UAAU,WAAW,EAAE,EAC/C;AACF;AAEA,SAAS,YACP,KACA,QACiB;CACjB,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,OAAO,MAAM,QAAQ;GAEnB,IACE,IAAI,cACJ,IAAI,cAAc,OAClB,IAAI,aAAa,OACjB,IAAI,QAAQ,UACZ;IACA,MAAM,cAAc,IAAI,QAAQ;IAIhC,YAAY,aAHW,YAAY,WAAW,UAAU,IACpDD,QACAC,GACmC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,MAAM,MAAM;IACnE;GACF;GAEA,IAAI,IAAI,cAAc,IAAI,cAAc,KAAK;IAC3C,uBAAO,IAAI,MAAM,mBAAmB,IAAI,IAAI,IAAI,YAAY,CAAC;IAC7D;GACF;GAEA,IAAI,OAAO;GACX,IAAI,YAAY,MAAM;GACtB,IAAI,GAAG,SAAS,UAAW,QAAQ,KAAM;GACzC,IAAI,GAAG,aAAa,QAAQ,IAAI,CAAC;GACjC,IAAI,GAAG,SAAS,MAAM;EACxB,CAAC,CAAC,CAAC,GAAG,SAAS,MAAM;CACvB,CAAC;AACH;;;;AAKA,MAAa,iBAAyB,YAAY","debug_id":"8149a6c4-bab0-57e3-a471-cfc77d529bbf"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as ISubscribablePackageLoader, s as ISubscriptionOptions, u as PackagePieceEntry } from "../../types-CuSz_zv6.mjs";
|
|
2
2
|
import { ILogger } from "document-model";
|
|
3
3
|
import { DocumentModelModule, UpgradeManifest } from "@powerhousedao/shared/document-model";
|
|
4
4
|
import { Logger, ViteDevServer } from "vite";
|
|
5
5
|
import { ProcessorFactoryBuilder, SubgraphClass } from "@powerhousedao/reactor-api";
|
|
6
|
-
|
|
7
6
|
//#region src/packages/vite-loader.d.mts
|
|
8
|
-
declare function createViteLogger(logger: ILogger, prefix?: string): Logger;
|
|
9
|
-
declare class VitePackageLoader implements ISubscribablePackageLoader {
|
|
7
|
+
export declare function createViteLogger(logger: ILogger, prefix?: string): Logger;
|
|
8
|
+
export declare class VitePackageLoader implements ISubscribablePackageLoader {
|
|
10
9
|
#private;
|
|
11
10
|
private readonly logger;
|
|
12
11
|
private readonly vite;
|
|
@@ -16,15 +15,20 @@ declare class VitePackageLoader implements ISubscribablePackageLoader {
|
|
|
16
15
|
private getDocumentModelsPath;
|
|
17
16
|
private getSubgraphsPath;
|
|
18
17
|
private getProcessorsPath;
|
|
18
|
+
private getPiecesPath;
|
|
19
|
+
private aliasedRoot;
|
|
20
|
+
private pieceRoot;
|
|
19
21
|
loadDocumentModels(identifier: string, immediate?: boolean): Promise<DocumentModelModule[]>;
|
|
20
22
|
loadUpgradeManifests(identifier: string): Promise<UpgradeManifest<readonly number[]>[]>;
|
|
21
23
|
loadSubgraphs(identifier: string): Promise<SubgraphClass[]>;
|
|
22
24
|
loadProcessors(identifier: string): Promise<ProcessorFactoryBuilder | null>;
|
|
25
|
+
loadPieces(identifier: string): Promise<PackagePieceEntry[]>;
|
|
23
26
|
onDocumentModelsChange(identifier: string, handler: (documentModels: DocumentModelModule[]) => void, options?: ISubscriptionOptions): () => void;
|
|
24
27
|
onSubgraphsChange(identifier: string, handler: (subgraphs: SubgraphClass[]) => void, options?: ISubscriptionOptions): () => void;
|
|
25
28
|
onProcessorsChange(identifier: string, handler: (processors: ProcessorFactoryBuilder | null) => void, options?: ISubscriptionOptions): () => void;
|
|
29
|
+
onPiecesChange(identifier: string, handler: (pieces: PackagePieceEntry[]) => void, options?: ISubscriptionOptions): () => void;
|
|
26
30
|
}
|
|
27
|
-
declare function startViteServer(root: string, logger?: Logger): Promise<ViteDevServer>;
|
|
31
|
+
export declare function startViteServer(root: string, logger?: Logger): Promise<ViteDevServer>;
|
|
28
32
|
//#endregion
|
|
29
|
-
export {
|
|
33
|
+
export {};
|
|
30
34
|
//# sourceMappingURL=vite-loader.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-loader.d.mts","names":[],"sources":["../../../src/packages/vite-loader.mts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"vite-loader.d.mts","names":[],"sources":["../../../src/packages/vite-loader.mts"],"mappings":";;;;;;wBA4BgB,iBAAiB,QAAQ,SAAS,kBAAW;qBA2BhD,6BAA6B;;mBACvB;mBAEA;WAER;SAEF,MAAM,MAAM,gBAAa;EAIhC,YAAY,MAAM;UAIV;UAIA;UAIA;UAIA;UAMA;UASA;EAYD,mBAAmB,oBAAoB,sBAAiB,QAAA;EA2CzD,qBACJ,qBACC,QAAQ;EAkCL,cAAc,qBAAqB,QAAQ;EA4B3C,eACJ,qBACC,QAAQ;EAiCL,WAAW,qBAAqB,QAAQ;EA6B9C,uBACE,oBACA,UAAU,gBAAgB,gCAC1B,UAAU;EAwBZ,kBACE,oBACA,UAAU,WAAW,0BACrB,UAAU;EAuBZ,mBACE,oBACA,UAAU,YAAY,yCACtB,UAAU;EAuBZ,eACE,oBACA,UAAU,QAAQ,8BAClB,UAAU;;wBA2BQ,gBAAgB,cAAc,SAAS,SAAM,QAAA"}
|