@hachej/boring-core 0.1.78 → 0.1.80

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.
@@ -1,8 +1,12 @@
1
+ import postgres from 'postgres';
1
2
  import { C as CoreConfig } from './types-DDnayJjI.js';
2
3
  import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
3
4
 
5
+ type CoreMigrationSql = postgres.Sql;
4
6
  interface RunMigrationsOptions {
5
7
  migrationsFolder?: string;
8
+ /** Explicit app-owned migrations run under the same deployment lock. */
9
+ additionalMigrations?: Array<(sql: CoreMigrationSql) => Promise<void>>;
6
10
  }
7
11
  declare function runMigrations(config: CoreConfig, options?: RunMigrationsOptions): Promise<void>;
8
12
 
@@ -1,5 +1,5 @@
1
1
  import { RuntimeProvisioningContribution, RegisterAgentRoutesOptions } from '@hachej/boring-agent/server';
2
- import { DirPluginEntry, CreateWorkspaceAgentServerOptions } from '@hachej/boring-workspace/app/server';
2
+ import { DirPluginEntry, CreateWorkspaceAgentServerOptions, WorkspaceAgentServerPluginContext } from '@hachej/boring-workspace/app/server';
3
3
  import { WorkspaceServerPlugin, WorkspaceBridgeOperationDefinition, WorkspaceBridgeHandler, WorkspaceBridgeRuntimeEnvOptions, WorkspaceBridgeCallRequest, WorkspaceBridgeCallResponse } from '@hachej/boring-workspace/server';
4
4
  import { FastifyInstance } from 'fastify';
5
5
  import { C as CoreConfig } from '../../types-DDnayJjI.js';
@@ -70,6 +70,8 @@ interface CreateCoreWorkspaceAgentServerOptions extends Omit<RegisterAgentRoutes
70
70
  serveFrontend?: boolean;
71
71
  /** Optional best-effort telemetry sink. Defaults to core's DB-backed env helper. */
72
72
  telemetry?: TelemetrySink;
73
+ /** Verified actor resolver exposed only to boot-time internal plugins. */
74
+ trustedPluginActorResolver?: NonNullable<WorkspaceAgentServerPluginContext['trusted']>['actorResolver'];
73
75
  }
74
76
  type AgentPiOptions = RegisterAgentRoutesOptions['pi'];
75
77
  declare function createCoreWorkspaceAgentServer(options?: CreateCoreWorkspaceAgentServerOptions): Promise<CoreWorkspaceAgentServer>;
@@ -9,13 +9,13 @@ import {
9
9
  registerRoutes,
10
10
  registerSettingsRoutes,
11
11
  registerWorkspaceRoutes
12
- } from "../../chunk-DSENO5O4.js";
12
+ } from "../../chunk-VB2N2DG5.js";
13
13
  import {
14
14
  PostgresUserStore,
15
15
  PostgresWorkspaceStore,
16
16
  createDatabase,
17
17
  telemetryEvents
18
- } from "../../chunk-JBEKMYST.js";
18
+ } from "../../chunk-H5BQOHWR.js";
19
19
  import {
20
20
  noopTelemetry,
21
21
  safeCapture
@@ -768,15 +768,42 @@ async function createCoreWorkspaceAgentServer(options = {}) {
768
768
  ...defaultPluginDirEntries,
769
769
  ...options.plugins ?? []
770
770
  ];
771
- const pluginResolveContext = {
771
+ let workspaceAgentDispatcherResolver;
772
+ const trustedDispatcherProxy = {
773
+ async resolve(actor, resolveOptions) {
774
+ if (!workspaceAgentDispatcherResolver) throw new Error("workspace agent dispatcher is not ready");
775
+ return await workspaceAgentDispatcherResolver.resolve(actor, resolveOptions);
776
+ },
777
+ async resolveWithWorkspace(actor, resolveOptions) {
778
+ if (!workspaceAgentDispatcherResolver?.resolveWithWorkspace) {
779
+ throw new Error("workspace agent dispatcher binding is not ready");
780
+ }
781
+ return await workspaceAgentDispatcherResolver.resolveWithWorkspace(actor, resolveOptions);
782
+ }
783
+ };
784
+ const basePluginResolveContext = {
772
785
  workspaceRoot: pluginWorkspaceRoot,
773
786
  bridge: createUnavailableCorePluginBridge()
774
787
  };
788
+ const trustedPluginActorResolver = options.trustedPluginActorResolver ?? (async (request) => {
789
+ const workspaceId = await resolveAuthorizedWorkspaceId(request, workspaceStore);
790
+ const userId = request.user?.id;
791
+ if (!userId) throw httpError("authentication required", 401);
792
+ return { workspaceId, userId };
793
+ });
794
+ const trustedPluginResolveContext = {
795
+ ...basePluginResolveContext,
796
+ trusted: {
797
+ workspaceAgentDispatcherResolver: trustedDispatcherProxy,
798
+ actorResolver: trustedPluginActorResolver,
799
+ sql
800
+ }
801
+ };
775
802
  const resolvedPlugins = await Promise.all(
776
803
  pluginEntries.map(async (entry) => {
777
804
  const plugin = await resolveOnePluginEntry(
778
805
  entry,
779
- pluginResolveContext
806
+ "dir" in entry && entry.trust === "internal" ? trustedPluginResolveContext : basePluginResolveContext
780
807
  );
781
808
  assertWorkspaceBridgeHandlersTrusted(plugin, entry);
782
809
  return plugin;
@@ -902,7 +929,10 @@ async function createCoreWorkspaceAgentServer(options = {}) {
902
929
  getWorkspaceId: resolveWorkspaceId,
903
930
  getWorkspaceRoot: resolveRoot,
904
931
  getTrustedWorkspaceRoot: options.getTrustedWorkspaceRoot ?? (options.getWorkspaceRoot ? void 0 : async ({ workspaceId }) => await resolveWorkspaceRoot(workspaceRoot, workspaceId)),
905
- onWorkspaceAgentDispatcher: options.onWorkspaceAgentDispatcher,
932
+ onWorkspaceAgentDispatcher: (resolver) => {
933
+ workspaceAgentDispatcherResolver = resolver;
934
+ options.onWorkspaceAgentDispatcher?.(resolver);
935
+ },
906
936
  provisionRuntime: async ({ provisioningAdapter, runtimeLayout, workspaceId, request, runtimeMode }) => {
907
937
  if (!provisioningAdapter) return void 0;
908
938
  const runtimePlugins = [
@@ -56,6 +56,9 @@ async function runMigrations(config, options) {
56
56
  await db.execute(sql.raw("CREATE EXTENSION IF NOT EXISTS pgcrypto"));
57
57
  const migrationsFolder = options?.migrationsFolder ?? defaultMigrationsFolder();
58
58
  await migrate(db, { migrationsFolder });
59
+ for (const migration of options?.additionalMigrations ?? []) {
60
+ await migration(migrationClient);
61
+ }
59
62
  } finally {
60
63
  await db.execute(sql.raw(`SELECT pg_advisory_unlock(${ADVISORY_LOCK_ID})`));
61
64
  }
@@ -13,7 +13,7 @@ import {
13
13
  workspaceRuntimes,
14
14
  workspaceSettings,
15
15
  workspaces
16
- } from "./chunk-JBEKMYST.js";
16
+ } from "./chunk-H5BQOHWR.js";
17
17
  import {
18
18
  noopTelemetry,
19
19
  safeCapture
@@ -1,6 +1,6 @@
1
1
  import { U as UserStore, W as WorkspaceStore } from '../../types-Dm11Zm56.js';
2
2
  export { D as Database, c as createDatabase } from '../../types-Dm11Zm56.js';
3
- export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, F as FinishBudgetReservationInput, c as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, d as ModelBudgetExceededError, P as PostgresBudgetReservationStore, e as PostgresMeteringStore, f as PostgresModelBudgetStore, R as RecordUsageInput, g as RecordUsageResult, h as ReservationFinalStatus, i as ReserveBudgetInput, j as ReserveBudgetResult, k as ReserveInput, l as ReserveResult, m as RunMigrationsOptions, U as UserBudgetExceededError, r as runMigrations } from '../../PostgresModelBudgetStore-D5GHv0fE.js';
3
+ export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, F as FinishBudgetReservationInput, c as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, d as ModelBudgetExceededError, P as PostgresBudgetReservationStore, e as PostgresMeteringStore, f as PostgresModelBudgetStore, R as RecordUsageInput, g as RecordUsageResult, h as ReservationFinalStatus, i as ReserveBudgetInput, j as ReserveBudgetResult, k as ReserveInput, l as ReserveResult, m as RunMigrationsOptions, U as UserBudgetExceededError, r as runMigrations } from '../../PostgresModelBudgetStore-BbqIF5TR.js';
4
4
  import { U as User, b as Workspace, E as ERROR_CODES, M as MemberRole, W as WorkspaceMember, c as WorkspaceInvite, d as WorkspaceRuntime, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput } from '../../types-DDnayJjI.js';
5
5
  import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
6
6
  import 'postgres';
@@ -11,7 +11,7 @@ import {
11
11
  UserBudgetExceededError,
12
12
  createDatabase,
13
13
  runMigrations
14
- } from "../../chunk-JBEKMYST.js";
14
+ } from "../../chunk-H5BQOHWR.js";
15
15
  import "../../chunk-QZGYKLXB.js";
16
16
  import "../../chunk-MLKGABMK.js";
17
17
  export {
@@ -9,8 +9,8 @@ import { IncomingMessage } from 'node:http';
9
9
  import { W as WorkspaceStore, C as CreateCoreAppOptions, D as Database, U as UserStore, a as WorkspaceProvisioner } from '../types-Dm11Zm56.js';
10
10
  export { A as AuthProvider, b as CapabilitiesContributor, P as ProvisionContext, d as ProvisionResult, c as createDatabase } from '../types-Dm11Zm56.js';
11
11
  import postgres from 'postgres';
12
- import { e as PostgresMeteringStore, C as CreditLedgerEntry } from '../PostgresModelBudgetStore-D5GHv0fE.js';
13
- export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, F as FinishBudgetReservationInput, c as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, d as ModelBudgetExceededError, P as PostgresBudgetReservationStore, f as PostgresModelBudgetStore, R as RecordUsageInput, g as RecordUsageResult, h as ReservationFinalStatus, i as ReserveBudgetInput, j as ReserveBudgetResult, k as ReserveInput, l as ReserveResult, U as UserBudgetExceededError, r as runMigrations } from '../PostgresModelBudgetStore-D5GHv0fE.js';
12
+ import { m as RunMigrationsOptions, e as PostgresMeteringStore, C as CreditLedgerEntry } from '../PostgresModelBudgetStore-BbqIF5TR.js';
13
+ export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, F as FinishBudgetReservationInput, c as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, d as ModelBudgetExceededError, P as PostgresBudgetReservationStore, f as PostgresModelBudgetStore, R as RecordUsageInput, g as RecordUsageResult, h as ReservationFinalStatus, i as ReserveBudgetInput, j as ReserveBudgetResult, k as ReserveInput, l as ReserveResult, U as UserBudgetExceededError, r as runMigrations } from '../PostgresModelBudgetStore-BbqIF5TR.js';
14
14
  import { T as TelemetrySink } from '../telemetry-DR18MeI0.js';
15
15
  import { AgentMeteringSink } from '@hachej/boring-agent/server';
16
16
  import 'better-auth';
@@ -361,7 +361,7 @@ interface WelcomeData {
361
361
  }
362
362
  declare function renderWelcome(data: WelcomeData): Promise<RenderedEmail>;
363
363
 
364
- interface RunCoreMigrationsFromEnvOptions {
364
+ interface RunCoreMigrationsFromEnvOptions extends RunMigrationsOptions {
365
365
  loadConfigOptions?: LoadConfigOptions;
366
366
  log?: Pick<Console, 'log'>;
367
367
  }
@@ -25,7 +25,7 @@ import {
25
25
  validateConfig,
26
26
  validatePasswordStrength,
27
27
  withUserSettingsWriteLock
28
- } from "../chunk-DSENO5O4.js";
28
+ } from "../chunk-VB2N2DG5.js";
29
29
  import {
30
30
  InsufficientCreditError,
31
31
  ModelBudgetExceededError,
@@ -35,7 +35,7 @@ import {
35
35
  UserBudgetExceededError,
36
36
  createDatabase,
37
37
  runMigrations
38
- } from "../chunk-JBEKMYST.js";
38
+ } from "../chunk-H5BQOHWR.js";
39
39
  import {
40
40
  noopTelemetry,
41
41
  safeCapture
@@ -78,7 +78,7 @@ function safeRedirect(url, config) {
78
78
  // src/server/migrations.ts
79
79
  async function runCoreMigrationsFromEnv(options = {}) {
80
80
  const config = await loadConfig(options.loadConfigOptions);
81
- await runMigrations(config);
81
+ await runMigrations(config, options);
82
82
  options.log?.log("migrations complete");
83
83
  }
84
84
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-core",
3
- "version": "0.1.78",
3
+ "version": "0.1.80",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Foundation package for boring-ui-v2 apps: DB, auth, config, HTTP app factory, and frontend app shell.",
@@ -79,9 +79,9 @@
79
79
  "react-router-dom": "^7.18.0",
80
80
  "smol-toml": "^1.7.0",
81
81
  "zod": "^3.25.76",
82
- "@hachej/boring-agent": "0.1.78",
83
- "@hachej/boring-workspace": "0.1.78",
84
- "@hachej/boring-ui-kit": "0.1.78"
82
+ "@hachej/boring-agent": "0.1.80",
83
+ "@hachej/boring-workspace": "0.1.80",
84
+ "@hachej/boring-ui-kit": "0.1.80"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@testing-library/jest-dom": "^6.9.1",